import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { useMemo, useState } from "react";
import { toast } from "sonner";
import { AppShell, PageHeader } from "@/components/app-shell";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";
import { Input, NativeSelect, Textarea } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  DONATIONS_MAILBOX,
  GRANTS_MAILBOX,
  INBOX_KIND_LABEL,
  type InboxKind,
} from "@/lib/constants";
import { getShellMeta } from "@/lib/server/api-core";
import { linkInboxToGift, listInbox, markInbox, simulateInboundMail } from "@/lib/server/api-inbox";
import { listRelationships } from "@/lib/server/api-pipeline";
import { formatDateTime, moneyCents } from "@/lib/utils";

export const Route = createFileRoute("/donations/inbox")({
  loader: async () => {
    const [meta, messages, relationships] = await Promise.all([
      getShellMeta(),
      listInbox(),
      listRelationships(),
    ]);
    return { meta, messages, relationships };
  },
  component: InboxPage,
});

function InboxPage() {
  const { meta, messages, relationships } = Route.useLoaderData();
  const router = useRouter();
  const [activeId, setActiveId] = useState(messages[0]?.id ?? "");
  const [open, setOpen] = useState(false);
  const [fromName, setFromName] = useState("");
  const [fromEmail, setFromEmail] = useState("");
  const [subject, setSubject] = useState("");
  const [body, setBody] = useState("");
  const [amount, setAmount] = useState("");
  const [relId, setRelId] = useState("");

  const active = useMemo(() => messages.find((m) => m.id === activeId) ?? messages[0], [messages, activeId]);

  async function mark(id: string, status: "read" | "unread" | "archived") {
    await markInbox({ data: { id, status } });
    await router.invalidate();
  }

  async function linkGift() {
    if (!active) return;
    try {
      const res = await linkInboxToGift({
        data: { id: active.id, relationshipId: relId || undefined, restricted: true },
      });
      toast.success(res.existing ? "Already recorded" : "Award posted to Layer 4");
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not record gift");
    }
  }

  async function simulate(e: React.FormEvent) {
    e.preventDefault();
    await simulateInboundMail({
      data: {
        from_name: fromName,
        from_email: fromEmail,
        subject,
        body,
        amount: amount ? Number(amount) : undefined,
        kind: amount ? "award" : "inbound",
      },
    });
    toast.success("Delivered to donations@");
    setOpen(false);
    await router.invalidate();
  }

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker="Super Admin · cPanel mailbox"
        title="Donations inbox"
        description={`${DONATIONS_MAILBOX} is provisioned on the CFL cPanel and forwards here. Award correspondence and DonorBox receipts land in Super Admin — they are never merged into a foundation grant.`}
        actions={
          <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
              <Button variant="outline">Simulate inbound</Button>
            </DialogTrigger>
            <DialogContent title="Deliver a message" description={`Writes to ${DONATIONS_MAILBOX}`}>
              <form className="flex flex-col gap-3" onSubmit={simulate}>
                <div className="grid gap-3 sm:grid-cols-2">
                  <div className="flex flex-col gap-1.5">
                    <Label>From name</Label>
                    <Input required value={fromName} onChange={(e) => setFromName(e.target.value)} />
                  </div>
                  <div className="flex flex-col gap-1.5">
                    <Label>From email</Label>
                    <Input required type="email" value={fromEmail} onChange={(e) => setFromEmail(e.target.value)} />
                  </div>
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label>Subject</Label>
                  <Input required value={subject} onChange={(e) => setSubject(e.target.value)} />
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label>Body</Label>
                  <Textarea required value={body} onChange={(e) => setBody(e.target.value)} />
                </div>
                <div className="flex flex-col gap-1.5">
                  <Label>Award amount (optional)</Label>
                  <Input type="number" min="0" step="1" value={amount} onChange={(e) => setAmount(e.target.value)} />
                </div>
                <Button type="submit">Deliver</Button>
              </form>
            </DialogContent>
          </Dialog>
        }
      />

      <div className="mb-6 grid gap-3 sm:grid-cols-2">
        <Card>
          <CardContent className="p-4">
            <p className="text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Primary mailbox</p>
            <p className="mt-1 font-mono text-sm text-primary">{DONATIONS_MAILBOX}</p>
            <p className="mt-1 text-xs text-muted-foreground">cPanel · forwards into this Super Admin panel</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="p-4">
            <p className="text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Grant correspondence alias</p>
            <p className="mt-1 font-mono text-sm text-primary">{GRANTS_MAILBOX}</p>
            <p className="mt-1 text-xs text-muted-foreground">Same inbox · LOI replies and award notices</p>
          </CardContent>
        </Card>
      </div>

      <div className="grid gap-4 lg:grid-cols-[340px_1fr]">
        <Card>
          <CardContent className="p-0">
            <ul className="divide-y divide-border">
              {messages.map((m) => (
                <li key={m.id}>
                  <button
                    type="button"
                    onClick={() => {
                      setActiveId(m.id);
                      if (m.status === "unread") void mark(m.id, "read");
                    }}
                    className={`flex w-full flex-col items-start gap-1 px-4 py-3 text-left hover:bg-muted/60 ${
                      active?.id === m.id ? "bg-primary/8" : ""
                    }`}
                  >
                    <div className="flex w-full items-center justify-between gap-2">
                      <p className="truncate text-sm font-medium">{m.from_name}</p>
                      {m.status === "unread" ? <span className="size-2 shrink-0 rounded-full bg-primary" /> : null}
                    </div>
                    <p className="truncate w-full text-sm text-muted-foreground">{m.subject}</p>
                    <div className="flex items-center gap-2">
                      <Badge variant={m.kind === "award" ? "success" : m.kind === "donorbox" ? "default" : "muted"}>
                        {INBOX_KIND_LABEL[m.kind as InboxKind] ?? m.kind}
                      </Badge>
                      <span className="text-[11px] text-muted-foreground">{formatDateTime(m.received_at)}</span>
                    </div>
                  </button>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>

        {active ? (
          <Card>
            <CardContent className="p-5">
              <div className="flex flex-wrap items-start justify-between gap-3">
                <div>
                  <p className="font-display text-xl font-semibold">{active.subject}</p>
                  <p className="mt-1 text-sm text-muted-foreground">
                    {active.from_name} · {active.from_email}
                  </p>
                  <p className="text-xs text-muted-foreground">
                    To {active.mailbox} · {formatDateTime(active.received_at)}
                  </p>
                </div>
                <Badge variant={active.kind === "award" ? "success" : "muted"}>
                  {INBOX_KIND_LABEL[active.kind as InboxKind] ?? active.kind}
                </Badge>
              </div>
              {active.amount_cents ? (
                <p className="mt-3 font-display text-2xl tabular text-success">{moneyCents(active.amount_cents)}</p>
              ) : null}
              <pre className="mt-5 whitespace-pre-wrap font-sans text-sm leading-relaxed">{active.body}</pre>

              {active.linked_solicitation_id ? (
                <Link
                  to="/outreach/$id"
                  params={{ id: active.linked_solicitation_id }}
                  className="mt-4 inline-block text-sm text-primary hover:underline"
                >
                  Open linked solicitation
                </Link>
              ) : null}
              {active.linked_foundation ? (
                <p className="mt-2 text-sm text-muted-foreground">Linked relationship · {active.linked_foundation}</p>
              ) : null}

              {active.kind === "award" && !active.linked_donation_id ? (
                <div className="mt-6 rounded-lg border border-border p-4">
                  <p className="text-sm font-medium">Record as Layer 4 gift</p>
                  <p className="mt-1 text-xs text-muted-foreground">
                    Closes the award into donations without merging it into the foundation record.
                  </p>
                  <div className="mt-3 flex flex-col gap-2">
                    <NativeSelect value={relId} onChange={(e) => setRelId(e.target.value)}>
                      <option value="">No relationship link</option>
                      {relationships.map((r) => (
                        <option key={r.id} value={r.id}>
                          {r.foundation_name}
                        </option>
                      ))}
                    </NativeSelect>
                    <Button onClick={linkGift}>Post gift from this email</Button>
                  </div>
                </div>
              ) : null}

              {active.linked_donation_id ? (
                <p className="mt-4 text-sm text-success">
                  Posted to Layer 4 ·{" "}
                  <Link to="/donations" className="underline-offset-4 hover:underline">
                    View activity
                  </Link>
                </p>
              ) : null}

              <div className="mt-6 flex flex-wrap gap-2">
                <Button variant="outline" size="sm" onClick={() => mark(active.id, "unread")}>
                  Mark unread
                </Button>
                <Button variant="archive" size="sm" onClick={() => mark(active.id, "archived")}>
                  Archive
                </Button>
              </div>
            </CardContent>
          </Card>
        ) : (
          <Card>
            <CardContent className="p-8 text-sm text-muted-foreground">No messages.</CardContent>
          </Card>
        )}
      </div>
    </AppShell>
  );
}
