'use client';

/**
 * Dialog: aus dem aktuellen Draft ein Trigger-Template freischalten.
 *
 * Flow:
 *  1. User vergibt Key + Name + optional Sender/Rate-Limit.
 *  2. Auto-extrahierte Variablen werden angezeigt (read-only im MVP).
 *  3. POST /api/trigger-templates → Klartext-API-Key zurück.
 *  4. Erfolgs-Screen mit Key + curl-Snippet, Button "Kopiert".
 */

import { useEffect, useMemo, useState } from 'react';
import { Loader2, Copy, X, ShieldCheck, Webhook } from 'lucide-react';

interface VariableHint { key: string; required: boolean; defaultValue?: string }

export interface PublishTriggerDialogProps {
  open: boolean;
  onClose: () => void;
  /** Aktuelles Draft, aus dem freigeschaltet wird. */
  draft: {
    workspaceId: string;
    subject: string;
    preheader: string;
    /** Bereits gerendertes MJML/HTML/Text — Worker friert das ein. */
    mjml: string;
    html: string;
    htmlText: string;
  } | null;
  /** Optional: Senders aus dem M365-Pool für Sender-Wahl. */
  m365Senders?: Array<{ email: string; name: string }>;
}

type Phase = 'form' | 'submitting' | 'success';

interface SuccessPayload {
  templateKey: string;
  apiKey: string;
  variableSchema: VariableHint[];
}

export function PublishTriggerDialog({ open, onClose, draft, m365Senders }: PublishTriggerDialogProps) {
  const [phase, setPhase] = useState<Phase>('form');
  const [key, setKey] = useState('');
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [senderEmail, setSenderEmail] = useState('');
  const [rateLimitPerHour, setRateLimitPerHour] = useState<string>('');
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<SuccessPayload | null>(null);
  const [copied, setCopied] = useState(false);

  // Bei Open Reset — Dialog ist transient. Bewusst setState in Effect: Open wird von
  // außen kontrolliert, ein vorgelagerter `key`-Reset am Parent ist hier nicht möglich
  // (Dialog rendert sich selbst, nicht durch ein Wrapping-Element). Pattern ist im
  // Codebase akzeptiert (z.B. useHoverPeek).
  useEffect(() => {
    if (open) {
      /* eslint-disable react-hooks/set-state-in-effect */
      setPhase('form');
      setKey('');
      setName('');
      setDescription('');
      setSenderEmail('');
      setRateLimitPerHour('');
      setError(null);
      setSuccess(null);
      setCopied(false);
      /* eslint-enable react-hooks/set-state-in-effect */
    }
  }, [open]);

  // Live-Preview der erkannten Variablen — gleiche Logik wie im Repo, hier client-seitig
  // für sofortiges Feedback. Server-seitige Extraktion ist autoritativ.
  const previewVariables = useMemo<string[]>(() => {
    if (!draft) return [];
    const SYSTEM = new Set([
      'RECIPIENT_ID', 'CRM_ID', 'EMAIL', 'FIRST_NAME',
      'CTA_PRIMARY_URL', 'CTA_SECONDARY_URL', 'LOGIN_LINK',
      'HERO_URL', 'UNSUBSCRIBE_URL', 'BROWSER_URL',
      'IMPRINT_URL', 'PRIVACY_URL', 'LOGO_URL',
      'BRAND_NAME', 'BRAND_PRIMARY_COLOR', 'BRAND_SECONDARY_COLOR',
      'TIPTAP_HTML',
    ]);
    const combined = `${draft.subject}\n${draft.preheader}\n${draft.mjml}`;
    const seen = new Set<string>();
    const out: string[] = [];
    for (const m of combined.matchAll(/\{\{\s*([A-Za-z_][A-Za-z0-9_.-]*)\s*\}\}/g)) {
      if (SYSTEM.has(m[1])) continue;
      if (seen.has(m[1])) continue;
      seen.add(m[1]);
      out.push(m[1]);
    }
    return out;
  }, [draft]);

  if (!open) return null;
  if (!draft) {
    return (
      <Backdrop onClose={onClose}>
        <Header title="Kein Draft geladen" subtitle="Bitte erst einen Draft öffnen, um daraus ein Trigger-Template freizuschalten." onClose={onClose} />
      </Backdrop>
    );
  }

  const submit = async () => {
    setError(null);
    if (!/^[a-z0-9_-]{2,64}$/.test(key)) {
      setError('Key muss aus a-z, 0-9, _ oder - bestehen (2-64 Zeichen)');
      return;
    }
    if (!name.trim()) {
      setError('Bitte einen Anzeige-Namen vergeben');
      return;
    }
    setPhase('submitting');
    try {
      const res = await fetch('/api/trigger-templates', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          key,
          name: name.trim(),
          description: description.trim() || undefined,
          workspaceId: draft.workspaceId,
          subject: draft.subject,
          preheader: draft.preheader,
          mjml: draft.mjml,
          html: draft.html,
          htmlText: draft.htmlText,
          senderEmail: senderEmail || undefined,
          rateLimitPerHour: rateLimitPerHour ? Number(rateLimitPerHour) : undefined,
        }),
      });
      const json = await res.json();
      if (!res.ok) {
        setError(json.error ?? 'Unbekannter Fehler');
        if (Array.isArray(json.issues)) setError(`${json.error}: ${json.issues.join(', ')}`);
        setPhase('form');
        return;
      }
      setSuccess({
        templateKey: json.template.key,
        apiKey: json.apiKey,
        variableSchema: (json.template.variableSchema ?? []) as VariableHint[],
      });
      setPhase('success');
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e));
      setPhase('form');
    }
  };

  return (
    <Backdrop onClose={phase === 'success' ? onClose : undefined}>
      <Header
        title={phase === 'success' ? 'Trigger-Template freigeschaltet' : 'Als Trigger freischalten'}
        subtitle={phase === 'success'
          ? 'API-Key bitte sofort kopieren — er wird nicht erneut angezeigt.'
          : 'Aus dem aktuellen Draft entsteht ein wiederverwendbares Template, das per HTTP-API ausgelöst werden kann.'
        }
        onClose={phase === 'submitting' ? undefined : onClose}
      />

      <div className="flex-1 overflow-y-auto px-6 py-5">
        {phase !== 'success' && (
          <div className="space-y-5">
            <Field label="Template-Key (URL-Slug)" hint="Wird Teil der API-URL: /api/trigger/{key}. Nur a-z, 0-9, _, -.">
              <input
                type="text"
                value={key}
                onChange={(e) => setKey(e.target.value.toLowerCase())}
                disabled={phase === 'submitting'}
                placeholder="order_confirmation"
                className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm font-mono dark:border-zinc-700 dark:bg-zinc-900"
              />
            </Field>

            <Field label="Anzeige-Name" hint="Nur intern für die Verwaltungsoberfläche.">
              <input
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
                disabled={phase === 'submitting'}
                placeholder="Bestellbestätigung"
                className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm dark:border-zinc-700 dark:bg-zinc-900"
              />
            </Field>

            <Field label="Beschreibung (optional)">
              <textarea
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                disabled={phase === 'submitting'}
                rows={2}
                placeholder="Wird vom Shop bei jeder neuen Bestellung getriggert."
                className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm dark:border-zinc-700 dark:bg-zinc-900"
              />
            </Field>

            {m365Senders && m365Senders.length > 0 && (
              <Field label="Absender (optional)" hint="Wenn leer, wird der Workspace-Default verwendet.">
                <select
                  value={senderEmail}
                  onChange={(e) => setSenderEmail(e.target.value)}
                  disabled={phase === 'submitting'}
                  className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm dark:border-zinc-700 dark:bg-zinc-900"
                >
                  <option value="">Workspace-Default (über companyId)</option>
                  {m365Senders.map(s => (
                    <option key={s.email} value={s.email}>{s.name} &lt;{s.email}&gt;</option>
                  ))}
                </select>
              </Field>
            )}

            <Field label="Rate-Limit (optional)" hint="Maximale Trigger pro Stunde. Schützt vor versehentlichem Loop im Shop.">
              <input
                type="number"
                value={rateLimitPerHour}
                onChange={(e) => setRateLimitPerHour(e.target.value)}
                disabled={phase === 'submitting'}
                placeholder="z.B. 1000 (leer = unbegrenzt)"
                min={1}
                className="w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-sm dark:border-zinc-700 dark:bg-zinc-900"
              />
            </Field>

            <div className="rounded-md border border-zinc-200 bg-zinc-50 p-3 dark:border-zinc-800 dark:bg-zinc-900/50">
              <div className="mb-2 flex items-center gap-2 text-xs font-medium text-zinc-700 dark:text-zinc-300">
                <Webhook className="h-3.5 w-3.5" />
                Erkannte Variablen ({previewVariables.length})
              </div>
              {previewVariables.length === 0 ? (
                <p className="text-xs text-zinc-500">
                  Keine User-Variablen im Template. Das Template würde für alle Empfänger identisch versendet.
                </p>
              ) : (
                <div className="flex flex-wrap gap-1.5">
                  {previewVariables.map(v => (
                    <code key={v} className="rounded bg-white px-2 py-0.5 text-xs font-mono text-blue-700 ring-1 ring-zinc-200 dark:bg-zinc-950 dark:text-blue-300 dark:ring-zinc-800">
                      {`{{${v}}}`}
                    </code>
                  ))}
                </div>
              )}
              <p className="mt-2 text-[11px] text-zinc-500">
                Diese Variablen müssen vom Shop in <code className="font-mono">data</code> mitgeschickt werden.
                System-Tags wie <code className="font-mono">{`{{FIRST_NAME}}`}</code> kommen aus <code className="font-mono">to</code>.
              </p>
            </div>

            {error && (
              <div className="rounded-md border border-red-300 bg-red-50 p-3 text-xs text-red-700 dark:border-red-900 dark:bg-red-950/30 dark:text-red-300">
                {error}
              </div>
            )}
          </div>
        )}

        {phase === 'success' && success && (
          <SuccessPanel success={success} onCopy={() => { setCopied(true); setTimeout(() => setCopied(false), 2000); }} copied={copied} />
        )}
      </div>

      <footer className="flex items-center justify-end gap-2 border-t border-zinc-200 px-6 py-4 dark:border-zinc-800">
        {phase !== 'success' ? (
          <>
            <button
              onClick={onClose}
              disabled={phase === 'submitting'}
              className="rounded-md px-4 py-2 text-sm font-medium text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800"
            >
              Abbrechen
            </button>
            <button
              onClick={submit}
              disabled={phase === 'submitting'}
              className="inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-60"
            >
              {phase === 'submitting' && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
              <ShieldCheck className="h-3.5 w-3.5" />
              Freischalten und API-Key generieren
            </button>
          </>
        ) : (
          <button
            onClick={onClose}
            className="rounded-md bg-zinc-900 px-4 py-2 text-sm font-medium text-white hover:bg-zinc-700 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-white"
          >
            Fertig
          </button>
        )}
      </footer>
    </Backdrop>
  );
}

function Backdrop({ children, onClose }: { children: React.ReactNode; onClose?: () => void }) {
  return (
    <>
      <div className="fixed inset-0 z-40 bg-black/50 backdrop-blur-sm" onClick={onClose} />
      <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
        <div className="flex h-[min(640px,90vh)] w-full max-w-[600px] flex-col overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-2xl dark:border-zinc-800 dark:bg-zinc-950">
          {children}
        </div>
      </div>
    </>
  );
}

function Header({ title, subtitle, onClose }: { title: string; subtitle?: string; onClose?: () => void }) {
  return (
    <header className="flex items-start justify-between border-b border-zinc-200 px-6 py-4 dark:border-zinc-800">
      <div>
        <h2 className="text-base font-semibold">{title}</h2>
        {subtitle && <p className="mt-0.5 text-xs text-zinc-500">{subtitle}</p>}
      </div>
      {onClose && (
        <button onClick={onClose} className="rounded-md p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-zinc-800">
          <X className="h-4 w-4" />
        </button>
      )}
    </header>
  );
}

function Field({ label, hint, children }: { label: string; hint?: string; children: React.ReactNode }) {
  return (
    <label className="block">
      <div className="mb-1 text-xs font-medium text-zinc-700 dark:text-zinc-300">{label}</div>
      {children}
      {hint && <div className="mt-1 text-[11px] text-zinc-500">{hint}</div>}
    </label>
  );
}

function SuccessPanel({ success, onCopy, copied }: { success: SuccessPayload; onCopy: () => void; copied: boolean }) {
  const curlSnippet = useMemo(() => {
    const baseUrl = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000';
    return [
      `curl -X POST ${baseUrl}/api/trigger/${success.templateKey} \\`,
      `  -H "Authorization: Bearer ${success.apiKey}" \\`,
      `  -H "Content-Type: application/json" \\`,
      `  -d '${JSON.stringify({
        to: { email: 'kunde@beispiel.de', firstName: 'Max' },
        data: success.variableSchema.reduce<Record<string, string>>((acc, v) => {
          acc[v.key] = `<wert für ${v.key}>`;
          return acc;
        }, {}),
        idempotencyKey: 'order-12345',
      })}'`,
    ].join('\n');
  }, [success]);

  return (
    <div className="space-y-4">
      <div className="rounded-md border border-amber-300 bg-amber-50 p-4 dark:border-amber-900 dark:bg-amber-950/30">
        <div className="mb-2 flex items-center gap-2 text-sm font-semibold text-amber-900 dark:text-amber-200">
          <ShieldCheck className="h-4 w-4" />
          Dein API-Key — nur jetzt sichtbar
        </div>
        <div className="flex items-center gap-2">
          <code className="flex-1 select-all rounded bg-white px-3 py-2 font-mono text-xs text-zinc-900 ring-1 ring-amber-300 dark:bg-zinc-950 dark:text-zinc-100 dark:ring-amber-900">
            {success.apiKey}
          </code>
          <button
            onClick={() => { navigator.clipboard.writeText(success.apiKey); onCopy(); }}
            className="inline-flex items-center gap-1.5 rounded-md bg-amber-600 px-3 py-2 text-xs font-medium text-white hover:bg-amber-700"
          >
            <Copy className="h-3 w-3" />
            {copied ? 'Kopiert' : 'Kopieren'}
          </button>
        </div>
        <p className="mt-2 text-[11px] text-amber-800 dark:text-amber-300">
          Speichere ihn jetzt sicher (z.B. im Shop-Backend als ENV-Variable). Mailforge speichert nur den Hash und kann ihn nicht erneut anzeigen — nur rotieren.
        </p>
      </div>

      <div>
        <div className="mb-1.5 text-xs font-medium text-zinc-700 dark:text-zinc-300">Sofort testen</div>
        <pre className="overflow-x-auto rounded-md bg-zinc-900 p-3 text-[11px] text-zinc-100 ring-1 ring-zinc-200 dark:ring-zinc-800">
          <code>{curlSnippet}</code>
        </pre>
      </div>
    </div>
  );
}
