'use client';

import { useMemo, useState } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { RotateCcw, Save } from 'lucide-react';

import { PageHeader } from '@/components/shared/page-header';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { apiFetch } from '@/lib/api/client';

interface TemplateRow {
  key: string;
  label: string;
  description: string;
  mergeTokens: string[];
  defaultSubject: string;
  subjectOverride: string | null;
  effectiveSubject: string;
}

export function EmailTemplatesAdmin() {
  const qc = useQueryClient();
  const { data, isLoading, error } = useQuery({
    queryKey: ['admin-email-templates'],
    queryFn: () => apiFetch<{ data: TemplateRow[] }>('/api/v1/admin/email-templates'),
  });
  // Key-based remount: re-mount the body when the server-loaded row
  // signature changes so its useState seeds from fresh server data.
  // Replaces the prior useEffect(setDrafts, [rows]) sync.
  const sig = data?.data
    ? data.data.map((r) => `${r.key}:${r.subjectOverride ?? r.defaultSubject}`).join('|')
    : 'loading';
  return (
    <EmailTemplatesAdminBody key={sig} data={data} isLoading={isLoading} error={error} qc={qc} />
  );
}

function EmailTemplatesAdminBody({
  data,
  isLoading,
  error,
  qc,
}: {
  data: { data: TemplateRow[] } | undefined;
  isLoading: boolean;
  error: unknown;
  qc: ReturnType<typeof useQueryClient>;
}) {
  const rows = useMemo(() => data?.data ?? [], [data]);
  const [drafts, setDrafts] = useState<Record<string, string>>(() => {
    const next: Record<string, string> = {};
    for (const row of rows) {
      next[row.key] = row.subjectOverride ?? row.defaultSubject;
    }
    return next;
  });
  const [savingKey, setSavingKey] = useState<string | null>(null);
  const [message, setMessage] = useState<{ key: string; kind: 'ok' | 'err'; text: string } | null>(
    null,
  );

  async function save(row: TemplateRow, mode: 'save' | 'reset') {
    setSavingKey(row.key);
    setMessage(null);
    try {
      const subject = mode === 'reset' ? null : (drafts[row.key] ?? '');
      await apiFetch('/api/v1/admin/email-templates', {
        method: 'PUT',
        body: { key: row.key, subject },
      });
      await qc.invalidateQueries({ queryKey: ['admin-email-templates'] });
      setMessage({
        key: row.key,
        kind: 'ok',
        text: mode === 'reset' ? 'Reset to default' : 'Saved',
      });
    } catch (err) {
      setMessage({
        key: row.key,
        kind: 'err',
        text: err instanceof Error ? err.message : 'Failed',
      });
    } finally {
      setSavingKey(null);
    }
  }

  return (
    <div>
      <PageHeader
        title="Email templates"
        description="Customize the subject line of transactional emails per port. Body editing is the next iteration; for now the layout and HTML stay locked to the default template."
      />

      <div className="mt-6 space-y-4">
        {isLoading ? (
          <p className="text-sm text-muted-foreground py-6">Loading…</p>
        ) : error ? (
          <p className="text-sm text-red-600 py-6">
            Failed to load templates: {error instanceof Error ? error.message : 'unknown error'}
          </p>
        ) : (
          rows.map((row) => {
            const draft = drafts[row.key] ?? row.defaultSubject;
            const dirty =
              draft !== (row.subjectOverride ?? row.defaultSubject) ||
              (row.subjectOverride !== null && draft === row.defaultSubject);
            const overridden = row.subjectOverride !== null;
            return (
              <Card key={row.key}>
                <CardHeader className="pb-2">
                  <div className="flex items-center gap-2 flex-wrap">
                    <CardTitle className="text-base font-medium">{row.label}</CardTitle>
                    {overridden ? (
                      <Badge className="bg-blue-100 text-blue-800">Overridden</Badge>
                    ) : (
                      <Badge variant="secondary">Default</Badge>
                    )}
                  </div>
                  <CardDescription>{row.description}</CardDescription>
                </CardHeader>
                <CardContent className="space-y-3">
                  <div>
                    <label className="text-xs uppercase tracking-wide text-muted-foreground">
                      Subject
                    </label>
                    <Input
                      value={draft}
                      onChange={(e) =>
                        setDrafts((prev) => ({ ...prev, [row.key]: e.target.value }))
                      }
                      className="mt-1 font-mono text-sm"
                    />
                  </div>
                  <div className="text-xs text-muted-foreground">
                    Default: <code className="font-mono">{row.defaultSubject}</code>
                  </div>
                  <div className="text-xs text-muted-foreground">
                    Available tokens:{' '}
                    {row.mergeTokens.map((t) => (
                      <code key={t} className="mr-1 font-mono">{`{{${t}}}`}</code>
                    ))}
                  </div>
                  <div className="flex items-center gap-2">
                    <Button
                      size="sm"
                      onClick={() => save(row, 'save')}
                      disabled={savingKey === row.key || !dirty}
                    >
                      <Save className="h-3.5 w-3.5 mr-1.5" aria-hidden /> Save
                    </Button>
                    {overridden ? (
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => save(row, 'reset')}
                        disabled={savingKey === row.key}
                      >
                        <RotateCcw className="h-3.5 w-3.5 mr-1.5" aria-hidden /> Reset to default
                      </Button>
                    ) : null}
                    {message?.key === row.key ? (
                      <span
                        className={
                          message.kind === 'ok' ? 'text-sm text-green-600' : 'text-sm text-red-600'
                        }
                      >
                        {message.text}
                      </span>
                    ) : null}
                  </div>
                </CardContent>
              </Card>
            );
          })
        )}
      </div>
    </div>
  );
}
