import { createFileRoute, Link, useRouter } from "@tanstack/react-router";
import { toast } from "sonner";
import { AppShell, PageHeader } from "@/components/app-shell";
import { StageBadge } from "@/components/stage-badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { PIPELINE_STAGES, STAGE_LABEL, type Stage } from "@/lib/constants";
import type { Relationship } from "@/lib/types";
import { getShellMeta } from "@/lib/server/api-core";
import { holdRelationship, listRelationships, sendFromPipeline, transitionRelationship } from "@/lib/server/api-pipeline";
import { formatDate } from "@/lib/utils";

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

function PipelinePage() {
  const { meta, relationships } = Route.useLoaderData();
  const router = useRouter();

  async function move(id: string, stage: Stage) {
    try {
      await transitionRelationship({ data: { id, stage } });
      toast.success(`Moved to ${STAGE_LABEL[stage]}`);
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Transition blocked");
    }
  }

  async function send(id: string) {
    try {
      const res = await sendFromPipeline({ data: { id } });
      if (res.bounced) {
        toast.error("Bounced — email is no good", { description: res.reason ?? undefined });
      } else {
        toast.success("Sent · moved to Contacted");
      }
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not send");
    }
  }

  async function hold(id: string) {
    try {
      await holdRelationship({ data: { id } });
      toast.message("Holding — not sent");
      await router.invalidate();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not hold");
    }
  }

  return (
    <AppShell hold={meta.hold} unread={meta.unread} noticeCount={meta.noticeCount} inboxUnread={meta.inboxUnread}>
      <PageHeader
        kicker="Layer 3 · relationship stages"
        title="Pipeline"
        description="Send mails the request and moves the foundation to Contacted. Hold keeps it unsent. Contacted is not a manual step — it happens when you Send."
      />

      <div className="pipeline-scroll -mx-4 flex gap-3 overflow-x-auto px-4 pb-4 lg:mx-0 lg:grid lg:grid-cols-5 lg:overflow-visible lg:px-0">
        {PIPELINE_STAGES.map((stage) => {
          const cards = relationships.filter((r) => r.stage === stage);
          return (
            <div key={stage} className="w-[260px] shrink-0 lg:w-auto">
              <div className="mb-2 flex items-baseline justify-between rounded-md bg-primary px-2 py-1.5 text-primary-foreground">
                <p className="text-[11px] font-semibold tracking-[0.16em] uppercase">
                  {STAGE_LABEL[stage]}
                </p>
                <span className="tabular text-sm">{cards.length}</span>
              </div>
              <div className="flex flex-col gap-2">
                {cards.map((r) => (
                  <Card key={r.id}>
                    <CardContent className="p-3">
                      <Link
                        to="/foundations/$id"
                        params={{ id: r.foundation_id }}
                        className="font-medium hover:text-primary"
                      >
                        {r.foundation_name}
                      </Link>
                      <p className="text-xs text-muted-foreground">{r.foundation_state}</p>
                      <p className="mt-2 text-sm">{r.next_action}</p>
                      <p className="text-xs text-muted-foreground">Due {formatDate(r.next_action_due)}</p>
                      {r.officers[0] ? (
                        <p className="mt-2 text-xs text-muted-foreground">
                          {r.officers[0].name}, {r.officers[0].title}
                          {r.officers[0].email ? ` · ${r.officers[0].email}` : ""}
                        </p>
                      ) : null}
                      <CardActions r={r} onSend={send} onHold={hold} onMove={move} />
                    </CardContent>
                  </Card>
                ))}
              </div>
            </div>
          );
        })}
      </div>

      <div className="mt-6">
        <p className="mb-2 text-[11px] tracking-[0.16em] text-muted-foreground uppercase">Holding · parked</p>
        <div className="flex flex-wrap gap-2">
          {relationships
            .filter((r) => r.stage === "holding" || r.stage === "declined" || r.stage === "dormant")
            .map((r) => (
              <div key={r.id} className="flex flex-wrap items-center gap-2 rounded-lg bg-card px-3 py-2 shadow-[var(--shadow-border)]">
                <StageBadge stage={r.stage} />
                <Link to="/foundations/$id" params={{ id: r.foundation_id }} className="text-sm">
                  {r.foundation_name}
                </Link>
                {r.stage === "holding" ? (
                  <>
                    <Button size="sm" onClick={() => send(r.id)}>
                      Send
                    </Button>
                    <Button size="sm" variant="ghost" onClick={() => move(r.id, "identified")}>
                      Back to identified
                    </Button>
                  </>
                ) : (
                  <Button size="sm" variant="ghost" onClick={() => move(r.id, "identified")}>
                    Re-approach
                  </Button>
                )}
              </div>
            ))}
        </div>
      </div>
    </AppShell>
  );
}

function CardActions({
  r,
  onSend,
  onHold,
  onMove,
}: {
  r: Relationship;
  onSend: (id: string) => void;
  onHold: (id: string) => void;
  onMove: (id: string, stage: Stage) => void;
}) {
  if (r.stage === "identified") {
    return (
      <div className="mt-3 grid grid-cols-2 gap-2">
        <Button size="sm" onClick={() => onSend(r.id)}>
          Send
        </Button>
        <Button size="sm" variant="outline" onClick={() => onHold(r.id)}>
          Hold
        </Button>
      </div>
    );
  }
  if (r.stage === "contacted") {
    return (
      <div className="mt-3 grid grid-cols-2 gap-2">
        <Button size="sm" variant="outline" onClick={() => onMove(r.id, "meeting")}>
          Meeting
        </Button>
        <Button size="sm" variant="outline" onClick={() => onHold(r.id)}>
          Hold
        </Button>
      </div>
    );
  }
  if (r.stage === "meeting") {
    return (
      <div className="mt-3 grid grid-cols-2 gap-2">
        <Button size="sm" variant="outline" onClick={() => onMove(r.id, "proposal")}>
          Proposal
        </Button>
        <Button size="sm" variant="outline" onClick={() => onHold(r.id)}>
          Hold
        </Button>
      </div>
    );
  }
  if (r.stage === "proposal") {
    return (
      <div className="mt-3 grid grid-cols-2 gap-2">
        <Button size="sm" variant="outline" onClick={() => onMove(r.id, "gift")}>
          Gift
        </Button>
        <Button size="sm" variant="outline" onClick={() => onHold(r.id)}>
          Hold
        </Button>
      </div>
    );
  }
  return null;
}
