import React, { useState, useEffect, useRef } from "react";
import { STATUS_COLORS, STATUS_BG } from "../constants.js";

export function StatusBadge({ status }) {
  const color = STATUS_COLORS[status] || "#888";
  const bg = STATUS_BG[status] || "#f5f5f5";
  return (
    <span style={{
      display: "inline-block", padding: "2px 10px", borderRadius: 20,
      fontSize: 11, fontWeight: 600, letterSpacing: "0.04em",
      color, background: bg, border: `1.5px solid ${color}40`,
    }}>{status}</span>
  );
}

export function StatusSelect({ value, options, onChange }) {
  const color = STATUS_COLORS[value] || "#888";
  const bg = STATUS_BG[value] || "#f5f5f5";
  return (
    <select
      value={value}
      onChange={e => onChange(e.target.value)}
      onClick={e => e.stopPropagation()}
      style={{
        fontSize: 11, height: 26, padding: "0 20px 0 8px",
        background: bg, color, border: `1.5px solid ${color}40`,
        fontWeight: 600, borderRadius: 20, cursor: "pointer",
        fontFamily: "inherit", appearance: "auto",
      }}
    >
      {options.map(s => <option key={s} value={s}>{s}</option>)}
    </select>
  );
}

export function Header({ title, action }) {
  return (
    <div style={{ marginBottom: 10, paddingBottom: 7, borderBottom: "1px solid var(--border)" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <h1 style={{ fontFamily: "'Playfair Display', serif", fontSize: 30, fontWeight: 400, letterSpacing: "-0.02em", lineHeight: 1.1 }}>{title}</h1>
        {action}
      </div>
    </div>
  );
}

export function FormField({ label, children }) {
  return (
    <div className="form-group" style={{ marginBottom: 14 }}>
      <label>{label}</label>
      {children}
    </div>
  );
}

export function Modal({ title, onClose, onSave, saveLabel, hideSave, children, wide, overflow }) {
  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal" style={{ ...(wide ? { maxWidth: 740 } : {}), ...(overflow ? { overflow: "visible" } : {}) }}>
        <h2 style={{ fontFamily: "'Playfair Display', serif", fontWeight: 400, marginBottom: 26, fontSize: 24, letterSpacing: "-0.01em" }}>{title}</h2>
        {children}
        <div style={{ display: "flex", gap: 10, justifyContent: "flex-end", marginTop: 24, paddingTop: 20, borderTop: "1px solid var(--border2)" }}>
          <button className="btn btn-ghost" onClick={onClose}>Abbrechen</button>
          {!hideSave && <button className="btn btn-primary" onClick={onSave}>{saveLabel || "Speichern"}</button>}
        </div>
      </div>
    </div>
  );
}

export function StudioLogo({ settings, size = 24 }) {
  if (settings.logo) {
    const h = settings.logoSize || 60;
    return <img src={settings.logo} alt={settings.name} style={{ maxHeight: h, maxWidth: h * 5, display: "block" }} />;
  }
  return <div style={{ fontFamily: "'Playfair Display', serif", fontSize: size, fontWeight: 400, fontStyle: "italic", letterSpacing: "-0.01em" }}>{settings.name}</div>;
}

export function useConfirm() {
  const [pending, setPending] = useState(null);
  const askConfirm = (msg, confirmLabel = "Löschen") =>
    new Promise(resolve => setPending({ msg, confirmLabel, resolve }));
  const ConfirmModalEl = pending ? (
    <div style={{ position: "fixed", inset: 0, background: "rgba(26,26,24,0.5)", zIndex: 2000, display: "flex", alignItems: "center", justifyContent: "center" }}>
      <div style={{ background: "#f0ede8", borderRadius: 8, padding: "24px 28px", maxWidth: 400, width: "90%", fontFamily: "inherit", boxShadow: "0 8px 32px rgba(0,0,0,0.2)" }}>
        <div style={{ fontSize: 13, lineHeight: 1.6, color: "#1a1a18", marginBottom: 22 }}>{pending.msg}</div>
        <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
          <button className="btn btn-ghost" onClick={() => { pending.resolve(false); setPending(null); }}>Abbrechen</button>
          <button className="btn btn-danger" onClick={() => { pending.resolve(true); setPending(null); }}>{pending.confirmLabel}</button>
        </div>
      </div>
    </div>
  ) : null;
  return { askConfirm, ConfirmModalEl };
}

export function DateInput({ value, onChange, style, ...props }) {
  const toDE = (iso) => {
    if (!iso || !/^\d{4}-\d{2}-\d{2}$/.test(iso)) return "";
    return `${iso.slice(8, 10)}.${iso.slice(5, 7)}.${iso.slice(0, 4)}`;
  };
  const toISO = (de) => {
    const m = de.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
    if (!m) return null;
    const iso = `${m[3]}-${m[2].padStart(2, "0")}-${m[1].padStart(2, "0")}`;
    return isNaN(new Date(iso).getTime()) ? null : iso;
  };
  const [text, setText] = React.useState(() => toDE(value));
  React.useEffect(() => { const de = toDE(value); if (de !== text) setText(de); }, [value]);
  const handleChange = (e) => {
    const digits = e.target.value.replace(/\D/g, "").slice(0, 8);
    let fmt = "";
    if (digits.length <= 2) fmt = digits;
    else if (digits.length <= 4) fmt = `${digits.slice(0, 2)}.${digits.slice(2)}`;
    else fmt = `${digits.slice(0, 2)}.${digits.slice(2, 4)}.${digits.slice(4)}`;
    setText(fmt);
    const iso = toISO(fmt);
    if (iso) onChange({ target: { value: iso } });
  };
  return (
    <input
      type="text"
      value={text}
      onChange={handleChange}
      onBlur={() => { if (!toISO(text) && value) setText(toDE(value)); }}
      placeholder="TT.MM.JJJJ"
      style={style}
      {...props}
    />
  );
}

export function RichEditor({ value, onChange, minHeight = 420, compact = false }) {
  const editorRef = React.useRef(null);
  const isInternalChange = React.useRef(false);
  const lastValue = React.useRef(value);
  const savedRange = React.useRef(null);
  const colorInputRef = React.useRef(null);
  const [colorValue, setColorValue] = React.useState("#000000");

  // Only push content into DOM when value changes from outside (template load)
  useEffect(() => {
    if (!editorRef.current) return;
    if (value !== lastValue.current && !isInternalChange.current) {
      editorRef.current.innerHTML = value;
      lastValue.current = value;
    }
    isInternalChange.current = false;
  }, [value]);

  const saveSelection = () => {
    const sel = window.getSelection();
    if (sel && sel.rangeCount > 0 && editorRef.current?.contains(sel.anchorNode)) {
      savedRange.current = sel.getRangeAt(0).cloneRange();
    }
  };

  const restoreSelection = () => {
    editorRef.current?.focus();
    if (!savedRange.current) {
      // Place cursor at end if no saved range
      const range = document.createRange();
      range.selectNodeContents(editorRef.current);
      range.collapse(false);
      const sel = window.getSelection();
      if (sel) { sel.removeAllRanges(); sel.addRange(range); }
      return;
    }
    const sel = window.getSelection();
    if (sel) { sel.removeAllRanges(); sel.addRange(savedRange.current); }
  };

  const exec = (cmd, val = null) => {
    restoreSelection();
    document.execCommand(cmd, false, val);
    saveSelection();
    // Sync content after command
    isInternalChange.current = true;
    const html = editorRef.current?.innerHTML || "";
    lastValue.current = html;
    onChange(html);
  };



  const TB = ({ cmd, val, title, style: s, children }) => (
    <button
      onMouseDown={e => { e.preventDefault(); exec(cmd, val); }}
      title={title}
      style={{
        padding: "0 9px", height: 30, borderRadius: 4,
        border: "none", cursor: "pointer", fontFamily: "inherit", fontSize: 12,
        background: "transparent", color: "var(--text3)",
        display: "flex", alignItems: "center", justifyContent: "center",
        transition: "background 0.1s",
        ...s,
      }}
      onMouseEnter={e => e.currentTarget.style.background = "var(--border2)"}
      onMouseLeave={e => e.currentTarget.style.background = "transparent"}
    >{children}</button>
  );
  const Sep = () => <div style={{ width: 1, height: 16, background: "var(--border)", margin: "0 3px", flexShrink: 0 }} />;

  return (
    <div style={{ border: "1.5px solid var(--input-border)", borderRadius: 8, overflow: "hidden" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 1, padding: "5px 8px", borderBottom: "1px solid var(--border2)", background: "var(--surface2)" }}>
        <TB cmd="bold" title="Fett (Ctrl+B)" s={{ fontWeight: 700, minWidth: 28 }}>B</TB>
        <TB cmd="italic" title="Kursiv (Ctrl+I)" s={{ fontStyle: "italic", minWidth: 28 }}>I</TB>
        <TB cmd="underline" title="Unterstrichen (Ctrl+U)" s={{ textDecoration: "underline", minWidth: 28 }}>U</TB>
        <Sep />

        <TB cmd="justifyLeft" title="Linksbündig" s={{ padding: "0 7px" }}>
          <svg width="14" height="12" viewBox="0 0 14 12" fill="currentColor">
            <rect x="0" y="0" width="14" height="1.5" rx="0.75"/>
            <rect x="0" y="3.5" width="9" height="1.5" rx="0.75"/>
            <rect x="0" y="7" width="14" height="1.5" rx="0.75"/>
            <rect x="0" y="10.5" width="11" height="1.5" rx="0.75"/>
          </svg>
        </TB>
        <TB cmd="justifyCenter" title="Zentriert" s={{ padding: "0 7px" }}>
          <svg width="14" height="12" viewBox="0 0 14 12" fill="currentColor">
            <rect x="0" y="0" width="14" height="1.5" rx="0.75"/>
            <rect x="2.5" y="3.5" width="9" height="1.5" rx="0.75"/>
            <rect x="0" y="7" width="14" height="1.5" rx="0.75"/>
            <rect x="1.5" y="10.5" width="11" height="1.5" rx="0.75"/>
          </svg>
        </TB>
        <TB cmd="justifyRight" title="Rechtsbündig" s={{ padding: "0 7px" }}>
          <svg width="14" height="12" viewBox="0 0 14 12" fill="currentColor">
            <rect x="0" y="0" width="14" height="1.5" rx="0.75"/>
            <rect x="5" y="3.5" width="9" height="1.5" rx="0.75"/>
            <rect x="0" y="7" width="14" height="1.5" rx="0.75"/>
            <rect x="3" y="10.5" width="11" height="1.5" rx="0.75"/>
          </svg>
        </TB>
        <Sep />

        {/* Font size */}
        <select
          onMouseDown={saveSelection}
          onChange={e => { exec("fontSize", e.target.value); e.target.value = ""; }}
          title="Schriftgrösse"
          style={{
            width: 80, height: 26, border: "1px solid var(--border2)", borderRadius: 4,
            background: "transparent", color: "var(--text3)", fontSize: 11,
            padding: "0 4px", cursor: "pointer", outline: "none",
          }}
        >
          <option value="">Grösse</option>
          <option value="1">Klein</option>
          <option value="3">Normal</option>
          <option value="5">Gross</option>
          <option value="7">Titel</option>
        </select>

        <Sep />

        {/* Color */}
        <button
          onMouseDown={e => { e.preventDefault(); saveSelection(); colorInputRef.current?.click(); }}
          title="Textfarbe"
          style={{
            padding: "0 8px", height: 30, borderRadius: 4, border: "none",
            cursor: "pointer", background: "transparent",
            display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center",
            gap: 2, transition: "background 0.1s",
          }}
          onMouseEnter={e => e.currentTarget.style.background = "var(--border2)"}
          onMouseLeave={e => e.currentTarget.style.background = "transparent"}
        >
          <span style={{ fontSize: 13, fontWeight: 700, color: "var(--text3)", lineHeight: 1 }}>A</span>
          <div style={{ width: 14, height: 3, borderRadius: 1, background: colorValue }} />
        </button>
        <input
          ref={colorInputRef}
          type="color"
          value={colorValue}
          onChange={e => { setColorValue(e.target.value); exec("foreColor", e.target.value); }}
          style={{ position: "absolute", width: 0, height: 0, opacity: 0, pointerEvents: "none" }}
        />
      </div>

      {/* Editor */}
      <div
        ref={editorRef}
        contentEditable
        suppressContentEditableWarning
        onInput={() => {
          isInternalChange.current = true;
          const html = editorRef.current?.innerHTML || "";
          lastValue.current = html;
          onChange(html);
        }}
        onKeyUp={saveSelection}
        onMouseUp={saveSelection}
        onBlur={saveSelection}
        onPaste={e => {
          e.preventDefault();
          const text = e.clipboardData.getData("text/plain");
          restoreSelection();
          document.execCommand("insertText", false, text);
          saveSelection();
        }}
        style={{
          minHeight, padding: compact ? "8px 10px" : "20px 24px", outline: "none",
          fontSize: compact ? 12 : 13, lineHeight: 1.8, color: "var(--text)",
          background: "var(--surface)",
          fontFamily: "'DM Mono', 'Courier New', monospace",
        }}
      />
    </div>
  );
}

export function CalendarPopup({ value, onChange, onClose, align = "left", showClear = true }) {
  const [viewYM, setViewYM] = useState(() => {
    const d = value ? new Date(value + "T00:00:00") : new Date();
    return { year: d.getFullYear(), month: d.getMonth() };
  });
  const todayStr = new Date().toISOString().slice(0, 10);
  const { year, month } = viewYM;
  const firstDay = new Date(year, month, 1);
  const lastDay = new Date(year, month + 1, 0);
  const startWeekday = (firstDay.getDay() + 6) % 7;
  const cells = [];
  for (let i = 0; i < startWeekday; i++) cells.push(null);
  for (let d = 1; d <= lastDay.getDate(); d++) {
    cells.push(`${year}-${String(month + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`);
  }
  const prevMonth = () => { const d = new Date(year, month - 1, 1); setViewYM({ year: d.getFullYear(), month: d.getMonth() }); };
  const nextMonth = () => { const d = new Date(year, month + 1, 1); setViewYM({ year: d.getFullYear(), month: d.getMonth() }); };
  const select = (ds) => { onChange(ds); onClose(); };

  return (
    <div
      style={{
        position: "absolute",
        top: "calc(100% + 4px)",
        [align === "right" ? "right" : "left"]: 0,
        zIndex: 2000,
        background: "#f0ede8",
        border: "1px solid #e0dbd4",
        borderRadius: 8,
        padding: 12,
        boxShadow: "0 8px 28px rgba(0,0,0,0.16)",
        width: 232,
      }}
      onMouseDown={e => e.stopPropagation()}
    >
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
        <button onMouseDown={e => { e.preventDefault(); prevMonth(); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px 8px", fontSize: 14, color: "#888", lineHeight: 1 }}>←</button>
        <div style={{ fontFamily: "'Playfair Display', serif", fontSize: 13, color: "#1a1a18" }}>
          {firstDay.toLocaleDateString("de-CH", { month: "long", year: "numeric" })}
        </div>
        <button onMouseDown={e => { e.preventDefault(); nextMonth(); }} style={{ background: "none", border: "none", cursor: "pointer", padding: "2px 8px", fontSize: 14, color: "#888", lineHeight: 1 }}>→</button>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 2, marginBottom: 3 }}>
        {["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"].map(d => (
          <div key={d} style={{ textAlign: "center", fontSize: 9, color: "#aaa", padding: "2px 0" }}>{d}</div>
        ))}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7,1fr)", gap: 2 }}>
        {cells.map((ds, i) => {
          if (!ds) return <div key={i} />;
          const dow = new Date(ds + "T00:00:00").getDay();
          const isWeekend = dow === 0 || dow === 6;
          const isSelected = ds === value;
          const isToday = ds === todayStr;
          return (
            <button key={ds}
              onMouseDown={e => { e.preventDefault(); select(ds); }}
              style={{
                aspectRatio: "1", fontSize: 11, cursor: "pointer",
                fontFamily: "inherit", borderRadius: 4,
                border: isToday && !isSelected ? "1.5px solid #b07848" : "1.5px solid transparent",
                background: isSelected ? "#1a1a18" : "transparent",
                color: isSelected ? "#b07848" : isWeekend ? "#bbb" : "#1a1a18",
                fontWeight: isToday && !isSelected ? 600 : 400,
              }}
              onMouseEnter={e => { if (!isSelected) e.currentTarget.style.background = "#e8e3dc"; }}
              onMouseLeave={e => { if (!isSelected) e.currentTarget.style.background = "transparent"; }}
            >
              {new Date(ds + "T00:00:00").getDate()}
            </button>
          );
        })}
      </div>
      {showClear && value && (
        <div style={{ marginTop: 8, paddingTop: 8, borderTop: "1px solid #e0dbd4", textAlign: "center" }}>
          <button onMouseDown={e => { e.preventDefault(); onChange(""); onClose(); }}
            style={{ fontSize: 10, color: "#aaa", background: "none", border: "none", cursor: "pointer", fontFamily: "inherit" }}>
            Datum löschen
          </button>
        </div>
      )}
    </div>
  );
}

export function DatePicker({ value, onChange, style, placeholder, align = "left", ...props }) {
  const [open, setOpen] = useState(false);
  const wrapRef = useRef(null);
  const toDE = (iso) => {
    if (!iso || !/^\d{4}-\d{2}-\d{2}$/.test(iso)) return "";
    return `${iso.slice(8, 10)}.${iso.slice(5, 7)}.${iso.slice(0, 4)}`;
  };
  useEffect(() => {
    if (!open) return;
    const close = (e) => { if (!wrapRef.current?.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, [open]);
  return (
    <div ref={wrapRef} style={{ position: "relative", display: "inline-block", width: "100%" }}>
      <input
        type="text"
        value={toDE(value)}
        readOnly
        onClick={() => setOpen(o => !o)}
        placeholder={placeholder || "TT.MM.JJJJ"}
        style={{ cursor: "pointer", ...style }}
        {...props}
      />
      {open && (
        <CalendarPopup
          value={value}
          onChange={ds => onChange({ target: { value: ds } })}
          onClose={() => setOpen(false)}
          align={align}
        />
      )}
    </div>
  );
}

export function NavArrows({ onPrev, onNext, disabledNext = false }) {
  const btn = (onClick, disabled, children) => (
    <button
      onClick={disabled ? undefined : onClick}
      disabled={disabled}
      style={{
        background: "none", border: "none", padding: "0 11px", height: 30,
        cursor: disabled ? "default" : "pointer",
        color: disabled ? "var(--border2)" : "var(--text3)",
        fontSize: 17, lineHeight: 1, display: "flex", alignItems: "center",
        fontFamily: "inherit", flexShrink: 0,
      }}
    >{children}</button>
  );
  return (
    <div style={{ display: "flex", border: "1px solid var(--border2)", borderRadius: 20, overflow: "hidden" }}>
      {btn(onPrev, false, "‹")}
      <div style={{ width: 1, background: "var(--border2)", alignSelf: "stretch" }} />
      {btn(onNext, disabledNext, "›")}
    </div>
  );
}

export function useCalendarNav() {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    if (!open) return;
    const close = (e) => { if (!ref.current?.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, [open]);
  return { open, setOpen, ref };
}
