import { useEffect, useState } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { Copy, Mail } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { StatusBadge } from "@/components/ui-kit";
import { formatDateTime } from "@/lib/format";
import { listInvoiceEmails, sendInvoiceEmail } from "@/lib/invoice-email.functions";

type Props = {
  invoice: { id: string; invoice_number: string; status?: string } | null;
  defaultEmail?: string | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

/** Emails a posted invoice to a client address, with the send history for that invoice. */
export function InvoiceEmailDialog({ invoice, defaultEmail, open, onOpenChange }: Props) {
  const send = useServerFn(sendInvoiceEmail);
  const listLog = useServerFn(listInvoiceEmails);
  const [email, setEmail] = useState(defaultEmail ?? "");
  const [message, setMessage] = useState("");

  useEffect(() => {
    if (open) setEmail(defaultEmail ?? "");
  }, [open, defaultEmail]);

  const { data: log = [], refetch } = useQuery({
    queryKey: ["invoice-emails", invoice?.id],
    queryFn: async () => await listLog({ data: { invoiceId: invoice?.id ?? null } }),
    enabled: open && Boolean(invoice?.id),
  });

  const mutation = useMutation({
    mutationFn: async () => {
      if (!invoice) throw new Error("No invoice selected");
      return await send({ data: { invoiceId: invoice.id, recipient: email || null, message: message || null } });
    },
    onSuccess: (result) => {
      if (result.status === "sent") toast.success(`Invoice emailed to ${result.recipient}`);
      else if (result.status === "skipped") toast.warning(result.detail ?? "Recipient is not accepting email");
      else toast.error(result.detail ?? "Could not send the invoice email");
      void refetch();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const docUrl = invoice ? `${window.location.origin}/pay/${invoice.id}` : "";

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>Email invoice {invoice?.invoice_number ?? ""}</DialogTitle>
          <DialogDescription>
            Sends the client a branded invoice email with a link to the printable invoice document, which they can save
            as PDF from their browser.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-3">
          <div>
            <Label htmlFor="invoice-email-to">Client email</Label>
            <Input
              id="invoice-email-to"
              type="email"
              placeholder="client@example.com"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
          <div>
            <Label htmlFor="invoice-email-message">Message (optional)</Label>
            <Textarea
              id="invoice-email-message"
              rows={3}
              placeholder="Thanks for working with us — the invoice for this month is attached below."
              value={message}
              onChange={(e) => setMessage(e.target.value)}
            />
          </div>
          <div className="flex items-center gap-2 rounded-md border bg-muted/40 p-2 text-xs">
            <span className="truncate text-muted-foreground">{docUrl}</span>
            <Button
              size="sm"
              variant="ghost"
              onClick={() => {
                void navigator.clipboard.writeText(docUrl);
                toast.success("Invoice link copied");
              }}
            >
              <Copy className="mr-1 size-3" /> Copy
            </Button>
          </div>

          {log.length > 0 ? (
            <div className="max-h-40 space-y-2 overflow-y-auto rounded-md border p-2">
              {log.map((row) => (
                <div key={row.id} className="flex items-start justify-between gap-2 text-xs">
                  <div>
                    <div className="font-medium">{row.recipient}</div>
                    <div className="text-muted-foreground">
                      {formatDateTime(row.created_at)}
                      {row.detail ? ` · ${row.detail}` : ""}
                    </div>
                  </div>
                  <StatusBadge status={row.status} />
                </div>
              ))}
            </div>
          ) : null}
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Close
          </Button>
          <Button disabled={mutation.isPending} onClick={() => mutation.mutate()}>
            <Mail className="mr-2 size-4" /> {mutation.isPending ? "Sending…" : "Send invoice"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
