"use client";

import { useCallback, useEffect, useState } from "react";
import { Mail } from "lucide-react";
import { PageHeader } from "@/components/layout/PageHeader";
import { EmptyState } from "@/components/layout/EmptyState";
import { ErrorState } from "@/components/layout/ErrorState";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton";
import { Textarea } from "@/components/ui/textarea";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { apiFetch, errorMessageForUi } from "@/lib/api";
import { cn } from "@/lib/utils";
import {
  emailDeliveryBadgeVariant,
  formatEmailDeliveryStatus,
} from "@/lib/status";

type EmailTemplate = {
  id: string;
  key: string;
  name: string;
  description?: string | null;
  subject: string;
  htmlBody: string;
  textBody?: string | null;
  variables?: string[] | null;
  isActive: boolean;
  updatedAt: string;
};

type EmailDelivery = {
  id: string;
  templateKey: string;
  toEmail: string;
  subject: string;
  status: string;
  errorMessage?: string | null;
  createdAt: string;
};

export default function EmailTemplatesPage() {
  const [templates, setTemplates] = useState<EmailTemplate[]>([]);
  const [deliveries, setDeliveries] = useState<EmailDelivery[]>([]);
  const [selectedKey, setSelectedKey] = useState<string | null>(null);
  const [form, setForm] = useState({
    name: "",
    description: "",
    subject: "",
    htmlBody: "",
    textBody: "",
    isActive: true,
  });
  const [testTo, setTestTo] = useState("");
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [t, d] = await Promise.all([
        apiFetch<EmailTemplate[]>("/email-templates"),
        apiFetch<EmailDelivery[]>("/email-templates/deliveries?limit=20"),
      ]);
      setTemplates(t);
      setDeliveries(d);
      if (!selectedKey && t[0]) {
        selectTemplate(t[0]);
      } else if (selectedKey) {
        const current = t.find((item) => item.key === selectedKey);
        if (current) selectTemplate(current);
      }
    } catch (err) {
      setError(errorMessageForUi(err, "Failed to load templates"));
    } finally {
      setLoading(false);
    }
  }, [selectedKey]);

  useEffect(() => {
    void load();
    // eslint-disable-next-line react-hooks/exhaustive-deps -- initial load only
  }, []);

  function selectTemplate(template: EmailTemplate) {
    setSelectedKey(template.key);
    setForm({
      name: template.name,
      description: template.description ?? "",
      subject: template.subject,
      htmlBody: template.htmlBody,
      textBody: template.textBody ?? "",
      isActive: template.isActive,
    });
    setNotice(null);
  }

  const selected = templates.find((t) => t.key === selectedKey) ?? null;
  const variables = Array.isArray(selected?.variables) ? selected.variables : [];

  async function save() {
    if (!selectedKey) return;
    setBusy("save");
    setNotice(null);
    try {
      await apiFetch(`/email-templates/${selectedKey}`, {
        method: "PATCH",
        body: JSON.stringify(form),
      });
      setNotice("Template saved.");
      await load();
    } catch (err) {
      const message = errorMessageForUi(err, "Save failed");
      if (message) setNotice(message);
    } finally {
      setBusy(null);
    }
  }

  async function resetDefault() {
    if (!selectedKey) return;
    if (!window.confirm("Reset this template to the platform default copy?")) return;
    setBusy("reset");
    setNotice(null);
    try {
      await apiFetch(`/email-templates/${selectedKey}/reset`, { method: "POST" });
      setNotice("Reset to default.");
      await load();
    } catch (err) {
      const message = errorMessageForUi(err, "Reset failed");
      if (message) setNotice(message);
    } finally {
      setBusy(null);
    }
  }

  async function sendTest() {
    if (!selectedKey || !testTo.trim()) return;
    setBusy("test");
    setNotice(null);
    try {
      await apiFetch(`/email-templates/${selectedKey}/test`, {
        method: "POST",
        body: JSON.stringify({ to: testTo.trim() }),
      });
      setNotice(`Test email queued for ${testTo.trim()}.`);
      await load();
    } catch (err) {
      const message = errorMessageForUi(err, "Test send failed");
      if (message) setNotice(message);
    } finally {
      setBusy(null);
    }
  }

  return (
    <>
      <PageHeader
        title="Email templates"
        description="Manage transactional email copy for auth, billing, and MyGeotab events."
      />

      {loading ? (
        <div className="space-y-3">
          <Skeleton className="h-10 w-full" />
          <Skeleton className="h-64 w-full" />
        </div>
      ) : error ? (
        <ErrorState title="Could not load templates" message={error} />
      ) : templates.length === 0 ? (
        <EmptyState
          icon={Mail}
          title="No templates"
          description="Defaults will appear after the API starts once."
        />
      ) : (
        <div className="grid gap-6 xl:grid-cols-[320px_1fr]">
          <Card>
            <CardHeader>
              <CardTitle className="text-base">Events</CardTitle>
              <CardDescription>Select a template to edit subject and body.</CardDescription>
            </CardHeader>
            <CardContent className="space-y-1 p-2">
              {templates.map((template) => {
                const active = template.key === selectedKey;
                return (
                  <button
                    key={template.key}
                    type="button"
                    onClick={() => selectTemplate(template)}
                    className={cn(
                      "w-full rounded-md px-3 py-2 text-left text-sm transition-colors",
                      active ? "bg-primary/10 text-foreground" : "hover:bg-muted",
                    )}
                  >
                    <div className="flex items-center justify-between gap-2">
                      <span className="font-medium">{template.name}</span>
                      <Badge variant={template.isActive ? "default" : "secondary"}>
                        {template.isActive ? "On" : "Off"}
                      </Badge>
                    </div>
                    <p className="mt-0.5 text-xs text-muted-foreground">{template.key}</p>
                  </button>
                );
              })}
            </CardContent>
          </Card>

          {selected ? (
            <div className="space-y-4">
              <Card>
                <CardHeader>
                  <CardTitle>{selected.name}</CardTitle>
                  <CardDescription>{selected.description}</CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                  {notice ? (
                    <Alert>
                      <AlertTitle>Status</AlertTitle>
                      <AlertDescription>{notice}</AlertDescription>
                    </Alert>
                  ) : null}

                  <div className="grid gap-4 sm:grid-cols-2">
                    <div className="space-y-2">
                      <Label htmlFor="name">Name</Label>
                      <Input
                        id="name"
                        value={form.name}
                        onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
                      />
                    </div>
                    <div className="flex items-end gap-2 pb-1">
                      <div className="flex items-center gap-2">
                        <Checkbox
                          id="isActive"
                          checked={form.isActive}
                          onCheckedChange={(checked) =>
                            setForm((f) => ({ ...f, isActive: checked === true }))
                          }
                        />
                        <Label htmlFor="isActive" className="font-normal">
                          Active (send on event)
                        </Label>
                      </div>
                    </div>
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor="description">Description</Label>
                    <Input
                      id="description"
                      value={form.description}
                      onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))}
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor="subject">Subject</Label>
                    <Input
                      id="subject"
                      value={form.subject}
                      onChange={(e) => setForm((f) => ({ ...f, subject: e.target.value }))}
                    />
                  </div>

                  {variables.length ? (
                    <p className="text-xs text-muted-foreground">
                      Variables:{" "}
                      {variables.map((v) => (
                        <code key={v} className="mr-2 rounded bg-muted px-1 py-0.5">
                          {`{{${v}}}`}
                        </code>
                      ))}
                    </p>
                  ) : null}

                  <div className="space-y-2">
                    <Label htmlFor="htmlBody">HTML body</Label>
                    <Textarea
                      id="htmlBody"
                      className="min-h-[220px] font-mono"
                      value={form.htmlBody}
                      onChange={(e) => setForm((f) => ({ ...f, htmlBody: e.target.value }))}
                    />
                  </div>

                  <div className="space-y-2">
                    <Label htmlFor="textBody">Text body</Label>
                    <Textarea
                      id="textBody"
                      className="min-h-[120px] font-mono"
                      value={form.textBody}
                      onChange={(e) => setForm((f) => ({ ...f, textBody: e.target.value }))}
                    />
                  </div>

                  <div className="flex flex-wrap gap-2">
                    <Button onClick={() => void save()} disabled={busy !== null}>
                      {busy === "save" ? "Saving…" : "Save changes"}
                    </Button>
                    <Button variant="outline" onClick={() => void resetDefault()} disabled={busy !== null}>
                      {busy === "reset" ? "Resetting…" : "Reset to default"}
                    </Button>
                  </div>

                  <div className="flex flex-wrap items-end gap-2 border-t pt-4">
                    <div className="min-w-[220px] flex-1 space-y-2">
                      <Label htmlFor="testTo">Send test email</Label>
                      <Input
                        id="testTo"
                        type="email"
                        placeholder="you@company.com"
                        value={testTo}
                        onChange={(e) => setTestTo(e.target.value)}
                      />
                    </div>
                    <Button
                      variant="secondary"
                      onClick={() => void sendTest()}
                      disabled={busy !== null || !testTo.trim()}
                    >
                      {busy === "test" ? "Sending…" : "Send test"}
                    </Button>
                  </div>
                </CardContent>
              </Card>

              <Card>
                <CardHeader>
                  <CardTitle className="text-base">Recent deliveries</CardTitle>
                  <CardDescription>Last 20 platform email attempts.</CardDescription>
                </CardHeader>
                <CardContent>
                  {deliveries.length === 0 ? (
                    <p className="text-sm text-muted-foreground">No deliveries yet.</p>
                  ) : (
                    <Table>
                      <TableHeader>
                        <TableRow>
                          <TableHead>When</TableHead>
                          <TableHead>Template</TableHead>
                          <TableHead>To</TableHead>
                          <TableHead>Status</TableHead>
                        </TableRow>
                      </TableHeader>
                      <TableBody>
                        {deliveries.map((row) => (
                          <TableRow key={row.id}>
                            <TableCell className="whitespace-nowrap text-xs text-muted-foreground">
                              {new Date(row.createdAt).toLocaleString()}
                            </TableCell>
                            <TableCell className="text-xs">{row.templateKey}</TableCell>
                            <TableCell className="text-xs">{row.toEmail}</TableCell>
                            <TableCell>
                              <Badge variant={emailDeliveryBadgeVariant(row.status)}>
                                {formatEmailDeliveryStatus(row.status)}
                              </Badge>
                            </TableCell>
                          </TableRow>
                        ))}
                      </TableBody>
                    </Table>
                  )}
                </CardContent>
              </Card>
            </div>
          ) : null}
        </div>
      )}
    </>
  );
}
