"use client";

import { useMemo, useState, useTransition } from "react";
import { toast } from "sonner";
import { Plus, Trash2, Send } from "lucide-react";
import {
  createCategory,
  createTemplate,
  deleteTemplate,
  sendMail,
} from "./actions";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Tabs,
  TabsList,
  TabsTrigger,
  TabsContent,
} from "@/components/ui/tabs";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import type {
  ClientMailCategory,
  ClientMailTemplate,
} from "@/lib/types";

const NONE = "__none__";

type TemplateWithCategory = ClientMailTemplate & { categoryName?: string | null };

type LeadOption = { id: string; full_name: string | null; email: string };

export function ClientMailClient({
  categories,
  templates,
  leads,
  canManage,
  mailConfigured,
}: {
  categories: ClientMailCategory[];
  templates: TemplateWithCategory[];
  leads: LeadOption[];
  canManage: boolean;
  mailConfigured: boolean;
}) {
  return (
    <Tabs defaultValue="compose" className="space-y-4">
      <TabsList>
        <TabsTrigger value="compose">Compose</TabsTrigger>
        <TabsTrigger value="templates">Templates</TabsTrigger>
        <TabsTrigger value="categories">Categories</TabsTrigger>
      </TabsList>

      <TabsContent value="compose">
        <ComposeTab
          templates={templates}
          leads={leads}
          canManage={canManage}
          mailConfigured={mailConfigured}
        />
      </TabsContent>

      <TabsContent value="templates">
        <TemplatesTab
          templates={templates}
          categories={categories}
          canManage={canManage}
        />
      </TabsContent>

      <TabsContent value="categories">
        <CategoriesTab categories={categories} canManage={canManage} />
      </TabsContent>
    </Tabs>
  );
}

/* ---------------- Compose ---------------- */

function ComposeTab({
  templates,
  leads,
  canManage,
  mailConfigured,
}: {
  templates: TemplateWithCategory[];
  leads: LeadOption[];
  canManage: boolean;
  mailConfigured: boolean;
}) {
  const [subject, setSubject] = useState("");
  const [body, setBody] = useState("");
  const [templateId, setTemplateId] = useState<string>(NONE);
  const [selected, setSelected] = useState<Record<string, boolean>>({});
  const [filter, setFilter] = useState("");
  const [pending, startTransition] = useTransition();

  const selectedIds = useMemo(
    () => Object.keys(selected).filter((id) => selected[id]),
    [selected],
  );

  const filteredLeads = useMemo(() => {
    const q = filter.trim().toLowerCase();
    if (!q) return leads;
    return leads.filter(
      (l) =>
        (l.full_name ?? "").toLowerCase().includes(q) ||
        l.email.toLowerCase().includes(q),
    );
  }, [leads, filter]);

  function applyTemplate(value: string) {
    setTemplateId(value);
    if (value === NONE) return;
    const t = templates.find((x) => x.id === value);
    if (t) {
      setSubject(t.subject);
      setBody(t.body);
    }
  }

  function toggleAll(checked: boolean) {
    const next: Record<string, boolean> = {};
    if (checked) for (const l of filteredLeads) next[l.id] = true;
    setSelected(next);
  }

  function onSend() {
    if (!canManage) return;
    const recipients = leads
      .filter((l) => selected[l.id])
      .map((l) => ({ leadId: l.id, email: l.email, name: l.full_name }));

    if (recipients.length === 0) {
      toast.error("Select at least one recipient");
      return;
    }
    if (!subject.trim()) {
      toast.error("Subject is required");
      return;
    }
    if (!body.trim()) {
      toast.error("Body is required");
      return;
    }

    startTransition(async () => {
      const res = await sendMail({
        subject,
        body,
        templateId: templateId === NONE ? null : templateId,
        recipients,
      });
      if (res.error) {
        toast.error(res.error);
        return;
      }
      const parts: string[] = [];
      if (res.sent) parts.push(`${res.sent} sent`);
      if (res.queued) parts.push(`${res.queued} queued`);
      if (res.failed) parts.push(`${res.failed} failed`);
      toast.success(`Mail processed: ${parts.join(", ") || "0"}`);
      setSelected({});
    });
  }

  const allSelected =
    filteredLeads.length > 0 && filteredLeads.every((l) => selected[l.id]);

  return (
    <div className="grid gap-4 lg:grid-cols-2">
      <Card className="space-y-4 p-4">
        <div className="space-y-2">
          <Label>Use template</Label>
          <Select value={templateId} onValueChange={applyTemplate}>
            <SelectTrigger>
              <SelectValue placeholder="None" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value={NONE}>None</SelectItem>
              {templates.map((t) => (
                <SelectItem key={t.id} value={t.id}>
                  {t.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <div className="space-y-2">
          <Label htmlFor="subject">Subject *</Label>
          <Input
            id="subject"
            value={subject}
            onChange={(e) => setSubject(e.target.value)}
            placeholder="Email subject"
          />
        </div>

        <div className="space-y-2">
          <Label htmlFor="body">Body * (HTML allowed)</Label>
          <textarea
            id="body"
            value={body}
            onChange={(e) => setBody(e.target.value)}
            rows={10}
            className="flex min-h-[160px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
            placeholder="Write your message…"
          />
        </div>

        {!mailConfigured && (
          <p className="text-xs text-muted-foreground">
            RESEND is not configured — sends will be recorded as{" "}
            <span className="font-medium">queued</span> without external delivery.
          </p>
        )}

        <Button
          onClick={onSend}
          disabled={!canManage || pending}
          className="w-full"
        >
          <Send className="size-4" />
          {pending
            ? "Sending…"
            : `Send to ${selectedIds.length} recipient${selectedIds.length === 1 ? "" : "s"}`}
        </Button>
      </Card>

      <Card className="space-y-3 p-4">
        <div className="flex items-center justify-between gap-2">
          <Label>Recipients ({leads.length} with email)</Label>
          <Input
            value={filter}
            onChange={(e) => setFilter(e.target.value)}
            placeholder="Search…"
            className="h-8 max-w-[180px]"
          />
        </div>

        <label className="flex items-center gap-2 border-b pb-2 text-sm">
          <Checkbox
            checked={allSelected}
            onCheckedChange={(c) => toggleAll(c === true)}
          />
          Select all shown
        </label>

        <div className="max-h-[360px] space-y-1 overflow-y-auto">
          {filteredLeads.length === 0 ? (
            <p className="py-6 text-center text-sm text-muted-foreground">
              No leads with an email address.
            </p>
          ) : (
            filteredLeads.map((l) => (
              <label
                key={l.id}
                className="flex items-center gap-2 rounded px-1 py-1.5 text-sm hover:bg-muted/50"
              >
                <Checkbox
                  checked={!!selected[l.id]}
                  onCheckedChange={(c) =>
                    setSelected((prev) => ({ ...prev, [l.id]: c === true }))
                  }
                />
                <span className="font-medium">{l.full_name ?? "—"}</span>
                <span className="text-muted-foreground">{l.email}</span>
              </label>
            ))
          )}
        </div>
      </Card>
    </div>
  );
}

/* ---------------- Templates ---------------- */

function TemplatesTab({
  templates,
  categories,
  canManage,
}: {
  templates: TemplateWithCategory[];
  categories: ClientMailCategory[];
  canManage: boolean;
}) {
  const [pending, startTransition] = useTransition();

  function onDelete(id: string) {
    startTransition(async () => {
      const res = await deleteTemplate(id);
      if (res.error) toast.error(res.error);
      else toast.success("Template deleted");
    });
  }

  return (
    <Card className="space-y-4 p-4">
      <div className="flex items-center justify-between">
        <h2 className="text-sm font-medium">Email Templates</h2>
        {canManage && <AddTemplateDialog categories={categories} />}
      </div>
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Name</TableHead>
            <TableHead>Category</TableHead>
            <TableHead>Subject</TableHead>
            {canManage && <TableHead className="w-12" />}
          </TableRow>
        </TableHeader>
        <TableBody>
          {templates.length === 0 ? (
            <TableRow>
              <TableCell
                colSpan={canManage ? 4 : 3}
                className="py-10 text-center text-muted-foreground"
              >
                No templates yet.
              </TableCell>
            </TableRow>
          ) : (
            templates.map((t) => (
              <TableRow key={t.id}>
                <TableCell className="font-medium">{t.name}</TableCell>
                <TableCell>{t.categoryName ?? "—"}</TableCell>
                <TableCell className="text-muted-foreground">{t.subject}</TableCell>
                {canManage && (
                  <TableCell>
                    <Button
                      variant="ghost"
                      size="icon"
                      disabled={pending}
                      onClick={() => onDelete(t.id)}
                    >
                      <Trash2 className="size-4 text-destructive" />
                    </Button>
                  </TableCell>
                )}
              </TableRow>
            ))
          )}
        </TableBody>
      </Table>
    </Card>
  );
}

function AddTemplateDialog({
  categories,
}: {
  categories: ClientMailCategory[];
}) {
  const [open, setOpen] = useState(false);
  const [name, setName] = useState("");
  const [subject, setSubject] = useState("");
  const [body, setBody] = useState("");
  const [categoryId, setCategoryId] = useState<string>(NONE);
  const [pending, startTransition] = useTransition();

  function onSubmit() {
    if (!name.trim() || !subject.trim() || !body.trim()) {
      toast.error("Name, subject and body are required");
      return;
    }
    startTransition(async () => {
      const res = await createTemplate({
        name,
        subject,
        body,
        categoryId: categoryId === NONE ? null : categoryId,
      });
      if (res.error) {
        toast.error(res.error);
        return;
      }
      toast.success("Template created");
      setName("");
      setSubject("");
      setBody("");
      setCategoryId(NONE);
      setOpen(false);
    });
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button>
          <Plus className="size-4" /> Add Template
        </Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Add Template</DialogTitle>
        </DialogHeader>
        <div className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="t-name">Name *</Label>
            <Input
              id="t-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
            />
          </div>
          <div className="space-y-2">
            <Label>Category</Label>
            <Select value={categoryId} onValueChange={setCategoryId}>
              <SelectTrigger>
                <SelectValue placeholder="None" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={NONE}>None</SelectItem>
                {categories.map((c) => (
                  <SelectItem key={c.id} value={c.id}>
                    {c.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="t-subject">Subject *</Label>
            <Input
              id="t-subject"
              value={subject}
              onChange={(e) => setSubject(e.target.value)}
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="t-body">Body * (HTML allowed)</Label>
            <textarea
              id="t-body"
              value={body}
              onChange={(e) => setBody(e.target.value)}
              rows={8}
              className="flex min-h-[140px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50"
            />
          </div>
        </div>
        <DialogFooter>
          <Button onClick={onSubmit} disabled={pending}>
            {pending ? "Saving…" : "Save template"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

/* ---------------- Categories ---------------- */

function CategoriesTab({
  categories,
  canManage,
}: {
  categories: ClientMailCategory[];
  canManage: boolean;
}) {
  const [name, setName] = useState("");
  const [pending, startTransition] = useTransition();

  function onAdd() {
    if (!name.trim()) {
      toast.error("Name is required");
      return;
    }
    startTransition(async () => {
      const res = await createCategory(name);
      if (res.error) {
        toast.error(res.error);
        return;
      }
      toast.success("Category added");
      setName("");
    });
  }

  return (
    <Card className="space-y-4 p-4">
      <h2 className="text-sm font-medium">Categories</h2>
      {canManage && (
        <div className="flex max-w-md items-end gap-2">
          <div className="flex-1">
            <Input
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Enter category…"
              onKeyDown={(e) => {
                if (e.key === "Enter") onAdd();
              }}
            />
          </div>
          <Button onClick={onAdd} disabled={pending}>
            {pending ? "Adding…" : "Add"}
          </Button>
        </div>
      )}
      <div className="flex flex-wrap gap-2">
        {categories.length === 0 ? (
          <p className="text-sm text-muted-foreground">No categories yet.</p>
        ) : (
          categories.map((c) => (
            <Badge key={c.id} variant={c.is_active ? "default" : "secondary"}>
              {c.name}
            </Badge>
          ))
        )}
      </div>
    </Card>
  );
}
