"use client";

import { useCallback, useEffect, useState } from "react";
import { CalendarDays, Eye, Languages, MapPin, Pencil, Plus, RefreshCw, Search, Trash2 } from "lucide-react";
import { toast } from "react-hot-toast";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { ConfirmContentDeleteDialog } from "./confirm-content-delete-dialog";
import { TermsEditorDialog } from "./terms-editor-dialog";
import { TermsPreviewDialog } from "./terms-preview-dialog";
import { createTerms, deleteTerms, fetchCmsChannels, fetchTerms, updateTerms } from "./client-api";
import type { ContentChannel, TermsRecord } from "./types";

function formattedDate(value: string) {
  if (!value) return "No date set";
  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? "No date set" : date.toLocaleDateString(undefined, { year: "numeric", month: "long", day: "numeric", timeZone: "UTC" });
}

export function TermsView() {
  const [items, setItems] = useState<TermsRecord[]>([]);
  const [allItems, setAllItems] = useState<TermsRecord[]>([]);
  const [channels, setChannels] = useState<ContentChannel[]>([]);
  const [searchDraft, setSearchDraft] = useState("");
  const [search, setSearch] = useState("");
  const [status, setStatus] = useState<"" | "draft" | "published">("");
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [editorOpen, setEditorOpen] = useState(false);
  const [editing, setEditing] = useState<TermsRecord | null>(null);
  const [previewing, setPreviewing] = useState<TermsRecord | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<TermsRecord | null>(null);
  const [error, setError] = useState("");

  const load = useCallback(async (signal?: AbortSignal) => {
    setLoading(true);
    setError("");
    try {
      const [documents, channelRecords] = await Promise.all([
        fetchTerms({ search, status: status || undefined }, signal),
        fetchCmsChannels(signal),
      ]);
      setItems(documents);
      setChannels(channelRecords);
    } catch (cause) {
      if (cause instanceof DOMException && cause.name === "AbortError") return;
      setError(cause instanceof Error ? cause.message : "Unable to load Terms documents.");
    } finally {
      setLoading(false);
    }
  }, [search, status]);

  useEffect(() => {
    const controller = new AbortController();
    Promise.all([fetchTerms({ search, status: status || undefined }, controller.signal), fetchCmsChannels(controller.signal)])
      .then(([documents, channelRecords]) => {
        setItems(documents);
        setChannels(channelRecords);
        setError("");
      })
      .catch((cause: unknown) => {
        if (cause instanceof DOMException && cause.name === "AbortError") return;
        setError(cause instanceof Error ? cause.message : "Unable to load Terms documents.");
      })
      .finally(() => {
        if (!controller.signal.aborted) setLoading(false);
      });
    return () => controller.abort();
  }, [search, status]);

  async function openEditor(item: TermsRecord | null) {
    setEditing(item);
    setEditorOpen(true);
    try {
      setAllItems(await fetchTerms());
    } catch (cause) {
      setError(cause instanceof Error ? cause.message : "Unable to load available previous versions.");
    }
  }

  async function saveDocument(values: Parameters<typeof createTerms>[0]) {
    setSaving(true);
    try {
      if (editing) {
        await updateTerms(editing.id, values);
        toast.success("Terms & Conditions updated successfully.");
      } else {
        await createTerms(values);
        toast.success("Terms & Conditions created successfully.");
      }
      setEditorOpen(false);
      setEditing(null);
      await load();
    } finally {
      setSaving(false);
    }
  }

  async function confirmDelete() {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await deleteTerms(deleteTarget.id);
      setDeleteTarget(null);
      await load();
    } catch (cause) {
      setError(cause instanceof Error ? cause.message : "Unable to delete this Terms document.");
      setDeleteTarget(null);
    } finally {
      setDeleting(false);
    }
  }

  function applySearch() {
    const nextSearch = searchDraft.trim();
    if (nextSearch === search) {
      void load();
      return;
    }
    setLoading(true);
    setSearch(nextSearch);
  }

  return (
    <section className="rounded-xl border bg-card shadow-sm">
      <div className="flex flex-col gap-4 border-b p-5 sm:p-6">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h2 className="text-lg font-semibold">Terms & Conditions</h2>
            <p className="mt-1 text-sm text-muted-foreground">Manage published terms, drafts, and version history.</p>
          </div>
          <Button onClick={() => void openEditor(null)} disabled={loading}><Plus aria-hidden="true" /> Create document</Button>
        </div>
        <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
          <div className="relative min-w-0 flex-1">
            <Search aria-hidden="true" className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
            <Input value={searchDraft} onChange={(event) => setSearchDraft(event.target.value)} onKeyDown={(event) => { if (event.key === "Enter") applySearch(); }} placeholder="Search by title…" aria-label="Search Terms documents" className="pl-9" />
          </div>
          <select aria-label="Filter Terms by status" value={status} onChange={(event) => { setLoading(true); setStatus(event.target.value as typeof status); }} className="h-11 rounded-lg border border-input bg-card px-3 text-sm outline-none focus:border-primary sm:w-44">
            <option value="">All status</option>
            <option value="draft">Draft</option>
            <option value="published">Published</option>
          </select>
          <Button variant="outline" onClick={applySearch}>Search</Button>
          <Button variant="outline" size="icon" onClick={() => void load()} disabled={loading} aria-label="Refresh Terms documents"><RefreshCw aria-hidden="true" className={loading ? "animate-spin motion-reduce:animate-none" : ""} /></Button>
        </div>
      </div>

      <div className="p-5 sm:p-6">
        <div className="mb-4 text-sm text-muted-foreground" aria-live="polite">
          Showing <span className="font-semibold text-foreground">{loading ? "…" : items.length}</span> document{items.length === 1 ? "" : "s"}
        </div>
        {error && <p role="alert" className="mb-4 rounded-lg border border-destructive/30 bg-destructive/10 p-3 text-sm text-destructive">{error}</p>}
        {loading ? (
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3" aria-label="Loading Terms documents">
            {[1, 2, 3].map((row) => <div key={row} className="h-64 animate-pulse rounded-xl border bg-muted/30" />)}
          </div>
        ) : items.length === 0 ? (
          <div className="rounded-lg border border-dashed px-5 py-12 text-center">
            <h3 className="font-medium">No Terms documents found</h3>
            <p className="mt-1 text-sm text-muted-foreground">Create a document or update the filters.</p>
          </div>
        ) : (
          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
            {items.map((item) => (
              <article key={item.id} className="flex min-w-0 flex-col rounded-xl border bg-background p-5">
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <h3 className="line-clamp-2 font-semibold">{item.title}</h3>
                    {item.versionLabel && <p className="mt-1 text-sm text-muted-foreground">Version {item.versionLabel}</p>}
                  </div>
                  <span className={`shrink-0 rounded-full px-2.5 py-1 text-xs font-medium ${item.status === "published" ? "bg-emerald-500/10 text-emerald-700 dark:text-emerald-400" : "bg-amber-500/10 text-amber-800 dark:text-amber-300"}`}>{item.status}</span>
                </div>
                <dl className="mt-5 flex-1 space-y-3 text-sm">
                  <div className="flex items-start gap-2 text-muted-foreground"><CalendarDays aria-hidden="true" className="mt-0.5 size-4 shrink-0" /><div><dt className="sr-only">Effective date</dt><dd>Effective: {formattedDate(item.effectiveFrom)}</dd></div></div>
                  {item.jurisdiction && <div className="flex items-start gap-2 text-muted-foreground"><MapPin aria-hidden="true" className="mt-0.5 size-4 shrink-0" /><div><dt className="sr-only">Jurisdiction</dt><dd>{item.jurisdiction}</dd></div></div>}
                  {item.locale && <div className="flex items-start gap-2 text-muted-foreground"><Languages aria-hidden="true" className="mt-0.5 size-4 shrink-0" /><div><dt className="sr-only">Locale</dt><dd>{item.locale}</dd></div></div>}
                  {item.channelIds.length > 0 && <div className="pt-1 text-xs text-muted-foreground">Channels: {item.channelIds.map((id) => channels.find((channel) => channel.id === id)?.name ?? "Channel").join(", ")}</div>}
                </dl>
                <div className="mt-5 flex flex-wrap gap-2 border-t pt-4">
                  <Button type="button" variant="outline" size="sm" onClick={() => setPreviewing(item)}><Eye aria-hidden="true" /> Preview</Button>
                  <Button type="button" variant="outline" size="sm" onClick={() => void openEditor(item)}><Pencil aria-hidden="true" /> Edit</Button>
                  <Button type="button" variant="outline" size="sm" aria-label={`Delete ${item.title}`} onClick={() => setDeleteTarget(item)}><Trash2 aria-hidden="true" className="text-destructive" /><span className="sr-only sm:not-sr-only">Delete</span></Button>
                </div>
              </article>
            ))}
          </div>
        )}
      </div>

      {editorOpen && <TermsEditorDialog key={editing?.id ?? "new"} item={editing} documents={allItems.length ? allItems : items} channels={channels} open={editorOpen} busy={saving} onClose={() => { setEditorOpen(false); setEditing(null); }} onSave={saveDocument} />}
      {previewing && <TermsPreviewDialog key={previewing.id} item={previewing} open onClose={() => setPreviewing(null)} />}
      <ConfirmContentDeleteDialog open={!!deleteTarget} title="Delete this Terms document?" description={`“${deleteTarget?.title ?? "This document"}” will be removed from your organization’s content.`} busy={deleting} onClose={() => setDeleteTarget(null)} onConfirm={() => void confirmDelete()} />
    </section>
  );
}
