'use client';

/**
 * Schlanker Editor für eigene MJML/HTML-Sektionen im Briefing-Tab.
 *
 * Schreibt auf `briefing.extraSections` (BriefingSectionInstance[]). Speichert
 * Sections IMMER als wiederverwendbare `sectionTemplates`-Rows (kind='custom',
 * bodyMode='mjml_raw' | 'html_raw') — so können sie in anderen Kampagnen wieder-
 * verwendet werden. Per Toggle entscheidet der User, welche der gespeicherten
 * Custom-Sections in genau dieser Mail aktiv ist.
 *
 * Ersetzt die alte SectionInstanceList-UI im Edit-Panel. Vordefinierte Template-
 * Sections (Kontakt, FAQ, …) werden in dieser UI nicht angezeigt — Filter `kind=custom`.
 */

import { useCallback, useEffect, useMemo, useState } from 'react';
import { Boxes, Loader2, Pencil, Plus, Trash2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import type {
  BriefingSectionInstance,
  BriefingTipTapDoc,
  SectionBodyMode,
  SectionPosition,
} from './BriefingPanel';

interface SectionTemplate {
  id: string;
  workspaceId: string;
  kind: 'custom';
  name: string;
  description: string | null;
  defaultContentJson: BriefingTipTapDoc;
  mjmlBlock: string;
  defaultPosition: SectionPosition;
  bodyMode: SectionBodyMode;
  isSystem: boolean;
}

type RawBodyMode = 'mjml_raw' | 'html_raw';

const POSITION_LABELS: Record<SectionPosition, string> = {
  before_cta: 'Vor dem CTA',
  after_cta: 'Nach dem CTA',
  before_signature: 'Vor der Signatur',
  after_signature: 'Vor dem Footer',
};

const POSITION_OPTIONS: SectionPosition[] = [
  'before_cta',
  'after_cta',
  'before_signature',
  'after_signature',
];

const MJML_PLACEHOLDER =
  '<mj-section background-color="{{BRAND_PRIMARY_COLOR}}" padding="24px">\n  <mj-column>\n    <mj-text font-size="20px" color="#ffffff">Headline</mj-text>\n    <mj-button href="https://example.com" background-color="#ffffff" color="#000000">CTA</mj-button>\n  </mj-column>\n</mj-section>';

const HTML_PLACEHOLDER =
  '<table role="presentation" width="100%" style="background:#fbfaf7;padding:24px;">\n  <tr><td align="center">\n    <h1 style="margin:0;color:#222;">Headline</h1>\n    <a href="https://example.com" style="display:inline-block;padding:12px 24px;background:{{BRAND_PRIMARY_COLOR}};color:#fff;text-decoration:none;border-radius:8px;">CTA</a>\n  </td></tr>\n</table>';

const EMPTY_DOC: BriefingTipTapDoc = { type: 'doc', content: [] };

interface CreateFormState {
  open: boolean;
  name: string;
  position: SectionPosition;
  mode: RawBodyMode;
  body: string;
  saving: boolean;
  error: string | null;
}

interface EditFormState {
  open: boolean;
  name: string;
  position: SectionPosition;
  mode: RawBodyMode;
  body: string;
  saving: boolean;
  error: string | null;
}

const INITIAL_CREATE: CreateFormState = {
  open: false,
  name: '',
  position: 'after_cta',
  mode: 'mjml_raw',
  body: '',
  saving: false,
  error: null,
};

interface Props {
  workspaceSlug: string;
  value: BriefingSectionInstance[];
  onChange: (next: BriefingSectionInstance[]) => void;
}

export function CustomSectionEditor({ workspaceSlug, value, onChange }: Props) {
  const [templates, setTemplates] = useState<SectionTemplate[]>([]);
  const [loading, setLoading] = useState(false);
  const [listError, setListError] = useState<string | null>(null);
  const [createForm, setCreateForm] = useState<CreateFormState>(INITIAL_CREATE);
  const [editForms, setEditForms] = useState<Record<string, EditFormState>>({});

  const reload = useCallback(async () => {
    if (!workspaceSlug) {
      setTemplates([]);
      return;
    }
    setLoading(true);
    setListError(null);
    try {
      const res = await fetch(`/api/section-templates?workspaceSlug=${encodeURIComponent(workspaceSlug)}&kind=custom`);
      const data = await res.json();
      if (!res.ok || !data.ok) throw new Error(data.error ?? `Server returned ${res.status}`);
      // Filter im Frontend extra defensiv — wenn der Backend-Filter mal ausfällt,
      // bleibt die UI clean.
      const customs = (data.sections as SectionTemplate[]).filter((t) => t.kind === 'custom');
      setTemplates(customs);
    } catch (e) {
      setListError(e instanceof Error ? e.message : 'Laden fehlgeschlagen');
    } finally {
      setLoading(false);
    }
  }, [workspaceSlug]);

  useEffect(() => {
    void reload();
  }, [reload]);

  // Map templateId → existierende Instance im aktuellen Briefing.
  const instancesByTemplate = useMemo(() => {
    const out = new Map<string, BriefingSectionInstance>();
    for (const inst of value) out.set(inst.templateId, inst);
    return out;
  }, [value]);

  function patchInstance(templateId: string, patch: Partial<BriefingSectionInstance>) {
    const next = value.map((inst) => (inst.templateId === templateId ? { ...inst, ...patch } : inst));
    onChange(next);
  }

  function activateTemplate(template: SectionTemplate) {
    const existing = instancesByTemplate.get(template.id);
    if (existing) {
      patchInstance(template.id, { enabled: true });
      return;
    }
    const instance: BriefingSectionInstance = {
      instanceId: crypto.randomUUID(),
      templateId: template.id,
      kind: 'custom',
      enabled: true,
      position: template.defaultPosition,
      contentJson: EMPTY_DOC,
      customized: false,
      bodyMode: template.bodyMode,
      customBody: template.mjmlBlock,
    };
    onChange([...value, instance]);
  }

  function deactivateTemplate(templateId: string) {
    if (!instancesByTemplate.has(templateId)) return;
    patchInstance(templateId, { enabled: false });
  }

  async function deleteTemplate(template: SectionTemplate) {
    const ok = window.confirm(`Section "${template.name}" wirklich löschen? Sie verschwindet aus allen Kampagnen.`);
    if (!ok) return;
    try {
      const res = await fetch(`/api/section-templates/${template.id}`, { method: 'DELETE' });
      const data = await res.json();
      if (!res.ok || !data.ok) throw new Error(data.error ?? `Server returned ${res.status}`);
      // Aus Templates-Liste UND aus aktivem Briefing entfernen.
      setTemplates((prev) => prev.filter((t) => t.id !== template.id));
      onChange(value.filter((inst) => inst.templateId !== template.id));
    } catch (e) {
      setListError(e instanceof Error ? e.message : 'Löschen fehlgeschlagen');
    }
  }

  function openEdit(template: SectionTemplate) {
    const bodyMode: RawBodyMode = template.bodyMode === 'html_raw' ? 'html_raw' : 'mjml_raw';
    setEditForms((prev) => ({
      ...prev,
      [template.id]: {
        open: true,
        name: template.name,
        position: template.defaultPosition,
        mode: bodyMode,
        body: template.mjmlBlock,
        saving: false,
        error: null,
      },
    }));
  }

  function closeEdit(templateId: string) {
    setEditForms((prev) => {
      const next = { ...prev };
      delete next[templateId];
      return next;
    });
  }

  function patchEdit(templateId: string, patch: Partial<EditFormState>) {
    setEditForms((prev) => ({
      ...prev,
      [templateId]: { ...prev[templateId], ...patch },
    }));
  }

  async function saveEdit(template: SectionTemplate) {
    const form = editForms[template.id];
    if (!form) return;
    const name = form.name.trim();
    const body = form.body.trim();
    if (!name || body.length < 20) {
      patchEdit(template.id, { error: 'Name und MJML/HTML-Body (min. 20 Zeichen) sind Pflicht.' });
      return;
    }
    patchEdit(template.id, { saving: true, error: null });
    try {
      const res = await fetch(`/api/section-templates/${template.id}`, {
        method: 'PATCH',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          name,
          mjmlBlock: body,
          bodyMode: form.mode,
          defaultPosition: form.position,
        }),
      });
      const data = await res.json();
      if (!res.ok || !data.ok) throw new Error(data.error ?? `Server returned ${res.status}`);
      const updated = data.section as SectionTemplate;
      setTemplates((prev) => prev.map((t) => (t.id === template.id ? updated : t)));
      // Wenn diese Section im aktiven Briefing ist, customBody/bodyMode mitziehen.
      if (instancesByTemplate.has(template.id)) {
        patchInstance(template.id, {
          bodyMode: updated.bodyMode,
          customBody: updated.mjmlBlock,
          position: updated.defaultPosition,
        });
      }
      closeEdit(template.id);
    } catch (e) {
      patchEdit(template.id, {
        saving: false,
        error: e instanceof Error ? e.message : 'Speichern fehlgeschlagen',
      });
    }
  }

  async function submitCreate() {
    const name = createForm.name.trim();
    const body = createForm.body.trim();
    if (!name || body.length < 20) {
      setCreateForm((prev) => ({ ...prev, error: 'Name und MJML/HTML-Body (min. 20 Zeichen) sind Pflicht.' }));
      return;
    }
    setCreateForm((prev) => ({ ...prev, saving: true, error: null }));
    try {
      const res = await fetch('/api/section-templates', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          workspaceSlug,
          kind: 'custom',
          name,
          mjmlBlock: body,
          bodyMode: createForm.mode,
          defaultPosition: createForm.position,
          defaultContentJson: EMPTY_DOC,
        }),
      });
      const data = await res.json();
      if (!res.ok || !data.ok) throw new Error(data.error ?? `Server returned ${res.status}`);
      const created = data.section as SectionTemplate;
      setTemplates((prev) => [...prev, created]);
      // Direkt aktivieren — der häufigste UX-Pfad nach "Sektion anlegen" ist "in dieser Mail nutzen".
      activateTemplate(created);
      setCreateForm(INITIAL_CREATE);
    } catch (e) {
      setCreateForm((prev) => ({
        ...prev,
        saving: false,
        error: e instanceof Error ? e.message : 'Speichern fehlgeschlagen',
      }));
    }
  }

  return (
    <div className="flex flex-col gap-2">
      <p className="text-[11px] leading-relaxed text-zinc-500 dark:text-zinc-400">
        Eigene MJML- oder HTML-Blöcke, die nach dem Generate an einer wählbaren Position in die Mail eingefügt werden.
        Einmal gespeicherte Sektionen lassen sich in jeder Kampagne dieser Workspace wiederverwenden.
      </p>

      {listError && (
        <div className="rounded border border-rose-300 bg-rose-50 px-2 py-1 text-[11px] text-rose-700 dark:border-rose-900/60 dark:bg-rose-950/40 dark:text-rose-300">
          {listError}
        </div>
      )}

      {loading && templates.length === 0 ? (
        <div className="flex items-center gap-2 text-[11px] text-zinc-500">
          <Loader2 className="h-3 w-3 animate-spin" />
          Lade Sektionen …
        </div>
      ) : templates.length === 0 ? (
        <div className="rounded border border-dashed border-zinc-300 bg-zinc-50/50 px-3 py-2 text-[11px] text-zinc-500 dark:border-zinc-700 dark:bg-zinc-900/40">
          Noch keine eigenen Sektionen — lege unten deine erste an.
        </div>
      ) : (
        <ul className="flex flex-col gap-1.5">
          {templates.map((template) => {
            const instance = instancesByTemplate.get(template.id);
            const active = instance?.enabled ?? false;
            const editForm = editForms[template.id];
            const effectivePosition: SectionPosition = instance?.position ?? template.defaultPosition;
            return (
              <li
                key={template.id}
                className={cn(
                  'rounded-md border transition',
                  active
                    ? 'border-zinc-300 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900'
                    : 'border-zinc-200 bg-zinc-50/50 dark:border-zinc-800 dark:bg-zinc-900/30',
                )}
              >
                <div className="flex items-center gap-2 px-3 py-2">
                  <Boxes className={cn('h-3.5 w-3.5 shrink-0', active ? 'text-zinc-700 dark:text-zinc-300' : 'text-zinc-400')} />
                  <span className={cn('flex-1 truncate text-xs font-medium', active ? 'text-zinc-900 dark:text-zinc-100' : 'text-zinc-600 dark:text-zinc-400')}>
                    {template.name}
                  </span>
                  <span className="rounded bg-zinc-100 px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300">
                    {template.bodyMode === 'html_raw' ? 'HTML' : 'MJML'}
                  </span>
                  <button
                    type="button"
                    onClick={() => openEdit(template)}
                    className="rounded p-1 text-zinc-500 hover:bg-zinc-100 hover:text-zinc-800 dark:hover:bg-zinc-800 dark:hover:text-zinc-100"
                    title="Bearbeiten"
                  >
                    <Pencil className="h-3.5 w-3.5" />
                  </button>
                  <button
                    type="button"
                    onClick={() => deleteTemplate(template)}
                    className="rounded p-1 text-zinc-500 hover:bg-rose-50 hover:text-rose-600 dark:hover:bg-rose-950/40 dark:hover:text-rose-300"
                    title="Löschen"
                  >
                    <Trash2 className="h-3.5 w-3.5" />
                  </button>
                  <label className="flex shrink-0 items-center gap-1.5 text-[11px] text-zinc-600 dark:text-zinc-300">
                    <input
                      type="checkbox"
                      checked={active}
                      onChange={(e) => (e.target.checked ? activateTemplate(template) : deactivateTemplate(template.id))}
                      className="h-3.5 w-3.5 accent-zinc-900 dark:accent-zinc-100"
                    />
                    in dieser Mail
                  </label>
                </div>

                {active && (
                  <div className="flex flex-wrap items-center gap-2 border-t border-zinc-200 bg-zinc-50/60 px-3 py-1.5 text-[11px] dark:border-zinc-800 dark:bg-zinc-900/40">
                    <span className="text-zinc-500">Position:</span>
                    <select
                      value={effectivePosition}
                      onChange={(e) => patchInstance(template.id, { position: e.target.value as SectionPosition })}
                      className="rounded border border-zinc-200 bg-white px-1.5 py-0.5 text-[11px] focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
                    >
                      {POSITION_OPTIONS.map((p) => (
                        <option key={p} value={p}>
                          {POSITION_LABELS[p]}
                        </option>
                      ))}
                    </select>
                  </div>
                )}

                {editForm?.open && (
                  <div className="flex flex-col gap-2 border-t border-zinc-200 px-3 py-2 dark:border-zinc-800">
                    <input
                      type="text"
                      value={editForm.name}
                      onChange={(e) => patchEdit(template.id, { name: e.target.value })}
                      placeholder="Section-Name"
                      className="rounded border border-zinc-200 bg-white px-2 py-1 text-xs focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
                    />
                    <div className="flex items-center gap-2 text-[11px]">
                      <span className="text-zinc-500">Modus:</span>
                      <ModeToggle
                        value={editForm.mode}
                        onChange={(m) => patchEdit(template.id, { mode: m })}
                      />
                      <span className="text-zinc-500">·</span>
                      <span className="text-zinc-500">Position:</span>
                      <select
                        value={editForm.position}
                        onChange={(e) => patchEdit(template.id, { position: e.target.value as SectionPosition })}
                        className="rounded border border-zinc-200 bg-white px-1.5 py-0.5 text-[11px] focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
                      >
                        {POSITION_OPTIONS.map((p) => (
                          <option key={p} value={p}>
                            {POSITION_LABELS[p]}
                          </option>
                        ))}
                      </select>
                    </div>
                    <textarea
                      value={editForm.body}
                      onChange={(e) => patchEdit(template.id, { body: e.target.value })}
                      rows={8}
                      placeholder={editForm.mode === 'html_raw' ? HTML_PLACEHOLDER : MJML_PLACEHOLDER}
                      className="rounded border border-zinc-200 bg-white px-2 py-1 font-mono text-[11px] focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
                    />
                    {editForm.error && (
                      <div className="text-[11px] text-rose-600 dark:text-rose-400">{editForm.error}</div>
                    )}
                    <div className="flex items-center justify-end gap-2">
                      <button
                        type="button"
                        onClick={() => closeEdit(template.id)}
                        className="rounded px-2 py-1 text-[11px] text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
                      >
                        Abbrechen
                      </button>
                      <button
                        type="button"
                        onClick={() => saveEdit(template)}
                        disabled={editForm.saving}
                        className="inline-flex items-center gap-1 rounded bg-zinc-900 px-2.5 py-1 text-[11px] font-medium text-white hover:bg-zinc-700 disabled:opacity-50 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-300"
                      >
                        {editForm.saving && <Loader2 className="h-3 w-3 animate-spin" />}
                        Speichern
                      </button>
                    </div>
                  </div>
                )}
              </li>
            );
          })}
        </ul>
      )}

      {createForm.open ? (
        <div className="flex flex-col gap-2 rounded-md border border-zinc-300 bg-white px-3 py-2 dark:border-zinc-700 dark:bg-zinc-900">
          <input
            type="text"
            value={createForm.name}
            onChange={(e) => setCreateForm((prev) => ({ ...prev, name: e.target.value }))}
            placeholder="z.B. Disclaimer DSGVO"
            className="rounded border border-zinc-200 bg-white px-2 py-1 text-xs focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
          />
          <div className="flex items-center gap-2 text-[11px]">
            <span className="text-zinc-500">Modus:</span>
            <ModeToggle
              value={createForm.mode}
              onChange={(m) => setCreateForm((prev) => ({ ...prev, mode: m }))}
            />
            <span className="text-zinc-500">·</span>
            <span className="text-zinc-500">Position:</span>
            <select
              value={createForm.position}
              onChange={(e) => setCreateForm((prev) => ({ ...prev, position: e.target.value as SectionPosition }))}
              className="rounded border border-zinc-200 bg-white px-1.5 py-0.5 text-[11px] focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
            >
              {POSITION_OPTIONS.map((p) => (
                <option key={p} value={p}>
                  {POSITION_LABELS[p]}
                </option>
              ))}
            </select>
          </div>
          <textarea
            value={createForm.body}
            onChange={(e) => setCreateForm((prev) => ({ ...prev, body: e.target.value }))}
            rows={8}
            placeholder={createForm.mode === 'html_raw' ? HTML_PLACEHOLDER : MJML_PLACEHOLDER}
            className="rounded border border-zinc-200 bg-white px-2 py-1 font-mono text-[11px] focus:border-zinc-900 focus:outline-none dark:border-zinc-700 dark:bg-zinc-950"
          />
          {createForm.error && (
            <div className="text-[11px] text-rose-600 dark:text-rose-400">{createForm.error}</div>
          )}
          <div className="flex items-center justify-end gap-2">
            <button
              type="button"
              onClick={() => setCreateForm(INITIAL_CREATE)}
              className="rounded px-2 py-1 text-[11px] text-zinc-600 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
            >
              Abbrechen
            </button>
            <button
              type="button"
              onClick={submitCreate}
              disabled={createForm.saving}
              className="inline-flex items-center gap-1 rounded bg-zinc-900 px-2.5 py-1 text-[11px] font-medium text-white hover:bg-zinc-700 disabled:opacity-50 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-300"
            >
              {createForm.saving && <Loader2 className="h-3 w-3 animate-spin" />}
              Speichern &amp; aktivieren
            </button>
          </div>
        </div>
      ) : (
        <button
          type="button"
          onClick={() => setCreateForm({ ...INITIAL_CREATE, open: true })}
          disabled={!workspaceSlug}
          className="inline-flex items-center gap-1.5 self-start rounded-md border border-dashed border-zinc-300 bg-white px-2.5 py-1.5 text-[11px] font-medium text-zinc-700 transition hover:border-zinc-400 hover:bg-zinc-50 disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200 dark:hover:border-zinc-500 dark:hover:bg-zinc-800"
        >
          <Plus className="h-3 w-3" />
          Neue Sektion anlegen
        </button>
      )}
    </div>
  );
}

function ModeToggle({ value, onChange }: { value: RawBodyMode; onChange: (m: RawBodyMode) => void }) {
  return (
    <div className="inline-flex overflow-hidden rounded border border-zinc-200 dark:border-zinc-700">
      {(['mjml_raw', 'html_raw'] as RawBodyMode[]).map((m) => {
        const active = value === m;
        const label = m === 'mjml_raw' ? 'MJML' : 'HTML';
        return (
          <button
            key={m}
            type="button"
            onClick={() => onChange(m)}
            className={cn(
              'px-2 py-0.5 text-[11px] font-medium transition',
              active
                ? 'bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900'
                : 'bg-white text-zinc-600 hover:bg-zinc-100 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800',
            )}
          >
            {label}
          </button>
        );
      })}
    </div>
  );
}
