"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { Icon } from "@/components/ui/Icon";
import { DatePicker } from "@/components/ui/DatePicker";
import { createEntryAction, updateEntryAction } from "@/lib/protocols/actions";
import {
  ITEM_KINDS,
  KIND_META,
  TEMPLATES,
  isItemKind,
  orderSections,
  templateFor,
  type ItemKind,
} from "@/lib/protocols/templates";
import type { ProtocolEntryDTO } from "@/lib/protocols/queries";
import { EntryBlock, type EntryView } from "./EntryBlock";

type Draft = Record<string, string[]>;

function todayISO(): string {
  const d = new Date();
  const p = (n: number) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
}

/** Vorhandene Punkte nach Abschnitt gruppieren (leere Zeile zum Weitertippen). */
function draftFrom(entry: ProtocolEntryDTO | null, template: string): Draft {
  const draft: Draft = {};
  for (const kind of templateFor(template).sections) draft[kind] = [""];
  if (entry) {
    for (const item of entry.items) {
      draft[item.kind] = [...(draft[item.kind] ?? []).filter((v) => v !== ""), item.text];
    }
    for (const kind of Object.keys(draft)) draft[kind] = [...draft[kind], ""];
  }
  return draft;
}

export function EntryEditor({
  protocolId,
  protocolName,
  entry,
  onClose,
}: {
  protocolId: string;
  protocolName: string;
  entry: ProtocolEntryDTO | null;
  onClose: () => void;
}) {
  const router = useRouter();
  const isNew = !entry;

  const [template, setTemplate] = useState(entry?.template ?? "release");
  const [title, setTitle] = useState(entry?.title ?? "");
  const [version, setVersion] = useState(entry?.version ?? "");
  const [date, setDate] = useState(entry ? entry.date.slice(0, 10) : todayISO());
  const [summary, setSummary] = useState(entry?.summary ?? "");
  const [draft, setDraft] = useState<Draft>(() => draftFrom(entry, entry?.template ?? "release"));
  const [addingSection, setAddingSection] = useState(false);
  const [mobilePreview, setMobilePreview] = useState(false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const tpl = templateFor(template);
  const sections = orderSections(
    template,
    Object.keys(draft).filter((k): k is ItemKind => isItemKind(k)),
  );
  const missing = ITEM_KINDS.filter((k) => !sections.includes(k));

  // Mit Escape schließen.
  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const switchTemplate = (key: string) => {
    setTemplate(key);
    setDraft((prev) => {
      const next = { ...prev };
      for (const kind of templateFor(key).sections) {
        if (!next[kind]) next[kind] = [""];
      }
      return next;
    });
  };

  const setLine = (kind: string, index: number, value: string) => {
    setDraft((prev) => {
      const lines = [...(prev[kind] ?? [""])];
      lines[index] = value;
      // Nur hinten nachwachsen — sonst verschieben sich Felder unter dem Cursor.
      if (lines[lines.length - 1].trim() !== "") lines.push("");
      return { ...prev, [kind]: lines };
    });
  };

  const removeLine = (kind: string, index: number) =>
    setDraft((prev) => {
      const lines = (prev[kind] ?? []).filter((_, i) => i !== index);
      return { ...prev, [kind]: lines.length ? lines : [""] };
    });

  const addSection = (kind: ItemKind) => {
    setDraft((prev) => ({ ...prev, [kind]: prev[kind] ?? [""] }));
    setAddingSection(false);
  };

  const dropSection = (kind: string) =>
    setDraft((prev) => {
      const next = { ...prev };
      delete next[kind];
      return next;
    });

  const items = Object.entries(draft).flatMap(([kind, lines]) =>
    lines.filter((l) => l.trim()).map((text) => ({ kind, text })),
  );

  const preview: EntryView = {
    title,
    version: tpl.withVersion ? version : null,
    date,
    template,
    summary,
    isDraft: entry?.status === "DRAFT" || isNew,
    items: items.filter((i): i is { kind: ItemKind; text: string } => isItemKind(i.kind)),
  };

  const save = async (publish: boolean) => {
    setError(null);
    if (!title.trim()) return setError("Titel darf nicht leer sein.");
    if (!date) return setError("Bitte ein Datum wählen.");

    const payload = {
      protocolId,
      title,
      version,
      date,
      template,
      summary,
      publish,
      items,
    };

    setSaving(true);
    const res = isNew
      ? await createEntryAction(payload)
      : await updateEntryAction(entry!.id, payload);
    setSaving(false);

    if (res.error) return setError(res.error);
    onClose();
    router.refresh();
  };

  return (
    <div className="ed-overlay">
      <div className="ed-shell animate-in">
        {/* Kopfleiste */}
        <div className="ed-top">
          <span className="vault-mark" style={{ color: tpl.color, width: 34, height: 34 }}>
            <Icon name={tpl.icon} size={16} />
          </span>
          <div className="min-w-0 flex-1">
            <span className="eyebrow">{isNew ? "Neuer Eintrag" : "Eintrag bearbeiten"}</span>
            <div className="truncate text-sm font-black">{protocolName}</div>
          </div>
          <button
            className="btn btn-ghost btn-sm lg:hidden"
            onClick={() => setMobilePreview((v) => !v)}
          >
            <Icon name="eye" size={15} /> {mobilePreview ? "Bearbeiten" : "Vorschau"}
          </button>
          <button className="btn btn-ghost btn-sm" onClick={onClose} aria-label="Schließen">
            <Icon name="close" size={16} />
          </button>
        </div>

        {/* Zwei Spalten: links tippen, rechts sehen */}
        <div className="ed-body" data-preview={mobilePreview}>
          <div className="ed-pane">
            {error ? <p className="field-error mb-3">{error}</p> : null}

            <div className="ed-label">Vorlage</div>
            <div className="ed-tpls mb-4">
              {TEMPLATES.map((t) => (
                <button
                  key={t.key}
                  type="button"
                  className="ed-tpl"
                  data-active={template === t.key}
                  onClick={() => switchTemplate(t.key)}
                  style={{ ["--tpl" as string]: t.color }}
                  title={t.description}
                >
                  <Icon name={t.icon} size={14} />
                  {t.name}
                </button>
              ))}
            </div>

            <div className="ed-label">Titel</div>
            <input
              className="input mb-3"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder={tpl.titleHint}
              autoFocus={isNew}
              style={{ fontSize: "1rem", fontWeight: 800 }}
            />

            <div className="mb-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
              <div>
                <div className="ed-label">Datum</div>
                <DatePicker value={date} onChange={setDate} />
              </div>
              {tpl.withVersion ? (
                <div>
                  <div className="ed-label">Version</div>
                  <input
                    className="input vault-mono"
                    value={version}
                    onChange={(e) => setVersion(e.target.value)}
                    placeholder="1.4.0"
                    maxLength={40}
                  />
                </div>
              ) : null}
            </div>

            <div className="ed-label">Beschreibung (optional)</div>
            <textarea
              className="textarea mb-1"
              value={summary}
              onChange={(e) => setSummary(e.target.value)}
              placeholder="Worum geht es in diesem Eintrag?"
              style={{ minHeight: 60 }}
            />

            {/* Abschnitte */}
            <div className="mt-4 flex flex-col">
              {sections.map((kind) => {
                const meta = KIND_META[kind];
                const lines = draft[kind] ?? [""];
                const filled = lines.filter((l) => l.trim()).length;
                return (
                  <div key={kind} className="ed-block">
                    <div className="ed-kind" style={{ color: meta.color }}>
                      {meta.label}
                      {filled > 0 ? <span className="text-muted">{filled}</span> : null}
                      <button
                        type="button"
                        className="ed-kind-x"
                        onClick={() => dropSection(kind)}
                        title="Abschnitt ausblenden"
                      >
                        <Icon name="close" size={13} />
                      </button>
                    </div>

                    {lines.map((line, i) => (
                      <div key={i} className="ed-line">
                        <input
                          className="input"
                          value={line}
                          onChange={(e) => setLine(kind, i, e.target.value)}
                          placeholder={i === 0 ? meta.placeholder : "Weiterer Punkt …"}
                          onKeyDown={(e) => {
                            if (e.key === "Enter") {
                              e.preventDefault();
                              const inputs = e.currentTarget
                                .closest(".ed-block")
                                ?.querySelectorAll<HTMLInputElement>("input.input");
                              inputs?.[i + 1]?.focus();
                            }
                          }}
                        />
                        <button
                          type="button"
                          className="ed-line-x"
                          onClick={() => removeLine(kind, i)}
                          title="Punkt entfernen"
                          tabIndex={-1}
                        >
                          <Icon name="close" size={13} />
                        </button>
                      </div>
                    ))}
                  </div>
                );
              })}
            </div>

            {missing.length > 0 ? (
              <div className="mt-4">
                {addingSection ? (
                  <div className="flex flex-wrap gap-1.5">
                    {missing.map((kind) => (
                      <button
                        key={kind}
                        type="button"
                        className="gen-chip"
                        onClick={() => addSection(kind)}
                      >
                        <span
                          className="proto-dot"
                          style={{ background: KIND_META[kind].color, width: 7, height: 7 }}
                        />{" "}
                        {KIND_META[kind].label}
                      </button>
                    ))}
                    <button
                      type="button"
                      className="gen-chip"
                      onClick={() => setAddingSection(false)}
                    >
                      Abbrechen
                    </button>
                  </div>
                ) : (
                  <button type="button" className="ed-add" onClick={() => setAddingSection(true)}>
                    <Icon name="plus" size={13} /> Abschnitt
                  </button>
                )}
              </div>
            ) : null}
          </div>

          {/* Vorschau */}
          <div className="ed-pane">
            <div className="ed-label mb-2">Vorschau</div>
            <div className="ed-preview">
              <EntryBlock entry={preview} />
            </div>
          </div>
        </div>

        {/* Fußleiste */}
        <div className="ed-bottom">
          <span className="text-muted text-xs">
            {items.length === 0 ? "Noch keine Punkte" : `${items.length} Punkt(e)`}
          </span>
          <div className="flex items-center gap-2">
            <button className="btn btn-ghost" onClick={onClose} disabled={saving}>
              Abbrechen
            </button>
            <button
              className="btn btn-ghost"
              onClick={() => void save(false)}
              disabled={saving || !title.trim()}
              title="Nur für die Redaktion sichtbar"
            >
              Entwurf
            </button>
            <button
              className="btn btn-primary"
              onClick={() => void save(true)}
              disabled={saving || !title.trim()}
            >
              {saving ? "Speichern …" : "Veröffentlichen"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
