import { useMemo } from "react";
import { useNavigate } from "react-router-dom";
import {
  AlertCircle,
  Banknote,
  CircleDollarSign,
  Clock,
  Inbox,
  Receipt,
  TrendingDown,
} from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { PageHeader } from "@/components/PageHeader";
import { KpiCard } from "@/components/KpiCard";
import { ActivityFeed } from "@/components/ActivityFeed";
import { AnimatedNumber } from "@/components/AnimatedNumber";
import { DrillableCell } from "@/components/drill/DrillableCell";
import { fmt } from "@/lib/format";
import { eventKindToUrl } from "@/lib/event-routing";
import { useAppStore } from "@/store";
import { toast } from "sonner";

const MONTHS_BACK = 6;

function buildMonthly(claims: ReturnType<typeof useAppStore.getState>["claims"]) {
  const now = new Date();
  const months: {
    key: string;
    label: string;
    count: number;
    billed: number;
    received: number;
    denied: number;
  }[] = [];
  for (let i = MONTHS_BACK - 1; i >= 0; i--) {
    const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
    months.push({
      key: `${d.getFullYear()}-${d.getMonth()}`,
      label: d.toLocaleString("en-US", { month: "short" }),
      count: 0,
      billed: 0,
      received: 0,
      denied: 0,
    });
  }
  const index = new Map(months.map((m, i) => [m.key, i]));
  for (const c of claims) {
    const d = new Date(c.submissionDate);
    const k = `${d.getFullYear()}-${d.getMonth()}`;
    const i = index.get(k);
    if (i === undefined) continue;
    months[i]!.count += 1;
    months[i]!.billed += c.billedAmount;
    months[i]!.received += c.receivedAmount;
    if (c.status === "denied") months[i]!.denied += 1;
  }
  let running = 0;
  const ar: number[] = [];
  for (const m of months) {
    running += m.billed - m.received;
    ar.push(Math.max(0, running));
  }
  return {
    count: months.map((m) => m.count),
    billed: months.map((m) => m.billed),
    received: months.map((m) => m.received),
    ar,
    denialRate: months.map((m) => (m.count ? (m.denied / m.count) * 100 : 0)),
  };
}

export function Dashboard() {
  const claims = useAppStore((s) => s.claims);
  const providers = useAppStore((s) => s.providers);
  const activity = useAppStore((s) => s.activity);

  const navigate = useNavigate();

  const kpis = useMemo(() => {
    const billed = claims.reduce((s, c) => s + c.billedAmount, 0);
    const received = claims.reduce((s, c) => s + c.receivedAmount, 0);
    const outstandingAr = billed - received;
    const denied = claims.filter((c) => c.status === "denied").length;
    const denialRate = claims.length > 0 ? (denied / claims.length) * 100 : 0;
    const pending = claims.filter(
      (c) => c.status === "submitted" || c.status === "pending"
    ).length;
    return {
      count: claims.length,
      billed,
      received,
      outstandingAr,
      denialRate,
      pending,
    };
  }, [claims]);

  const monthly = useMemo(() => buildMonthly(claims), [claims]);

  const topProviders = useMemo(
    () => [...providers].sort((a, b) => b.claimCount - a.claimCount).slice(0, 4),
    [providers]
  );

  const topDenials = useMemo(
    () => claims.filter((c) => c.status === "denied").slice(0, 5),
    [claims]
  );

  // Stagger choreography — the hero lands first, then the KPIs in
  // a left-to-right wave, then the supporting cards. Total
  // choreography fits under 700ms.
  const heroDelay = 0;
  const kpiBase = 120;
  const kpiStep = 60;
  const sectionBase = kpiBase + kpiStep * 5 + 80;

  return (
    <div className="space-y-6 lg:space-y-10">
      {/* Hero — the dashboard's only moment of editorial display. The
          ghost total sits behind the greeting at single-digit opacity
          so it reads as a watermark, not a competing headline. */}
      <section
        className="relative animate-fade-in overflow-hidden"
        style={{ animationDelay: `${heroDelay}ms` }}
      >
        <div
          aria-hidden="true"
          className="pointer-events-none select-none absolute -left-4 top-1/2 -translate-y-1/2 whitespace-nowrap display text-foreground"
          style={{
            fontSize: "clamp(80px, 14vw, 168px)",
            letterSpacing: "-0.04em",
            opacity: 0.04,
            lineHeight: 1,
          }}
        >
          {fmt.usd(kpis.billed)}
        </div>

        <div className="relative z-10 flex items-end justify-between gap-4 sm:gap-6 flex-wrap">
          <div className="min-w-0">
            <PageHeader
              eyebrow={`Today · ${fmt.date(new Date().toISOString())}`}
              title={<>Good morning, Jordan.</>}
              subtitle={
                <>
                  <span className="display text-foreground">Three NPIs</span> are
                  in flight. {kpis.pending} claims pending, clearinghouse cycle
                  is normal.
                </>
              }
            />
          </div>
          <div className="flex items-center gap-2 rounded-full border border-border/60 bg-card/60 px-3 py-1.5 text-[11px] mono uppercase tracking-[0.12em] text-muted-foreground backdrop-blur">
            <span className="relative inline-flex h-1.5 w-1.5">
              <span className="absolute inline-flex h-full w-full rounded-full bg-[hsl(var(--success))] opacity-60 animate-ping" />
              <span className="relative inline-flex h-1.5 w-1.5 rounded-full bg-[hsl(var(--success))]" />
            </span>
            Clearinghouse live
          </div>
        </div>
      </section>

      {/* KPIs — five tiles, each carrying a sparkline. Staggered
          fade-in on first paint for a "the instrument powers up"
          feel. */}
      <section
        aria-label="Key performance indicators"
        className="grid gap-3.5 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5"
      >
        <DrillableCell
          onClick={() => navigate("/claims")}
          ariaLabel="View all claims"
        >
          <KpiCard
            label="Claims"
            icon={Receipt}
            sparkline={monthly.count}
            className="animate-fade-in-up"
            style={{ animationDelay: `${kpiBase + 0 * kpiStep}ms` }}
            value={
              <AnimatedNumber value={kpis.count} format={(n) => fmt.num(Math.round(n))} />
            }
            hint="last 6 months"
          />
        </DrillableCell>
        <DrillableCell
          onClick={() => navigate("/claims?sort=-billedAmount")}
          ariaLabel="View claims sorted by billed amount"
        >
          <KpiCard
            label="Billed"
            icon={CircleDollarSign}
            accent="accent"
            sparkline={monthly.billed}
            className="animate-fade-in-up"
            style={{ animationDelay: `${kpiBase + 1 * kpiStep}ms` }}
            value={<AnimatedNumber value={kpis.billed} format={fmt.usd} />}
            delta={{ value: "+12.4%", direction: "up", positive: true }}
          />
        </DrillableCell>
        <DrillableCell
          onClick={() => navigate("/claims?sort=-receivedAmount")}
          ariaLabel="View claims sorted by received amount"
        >
          <KpiCard
            label="Received"
            icon={Banknote}
            accent="success"
            sparkline={monthly.received}
            className="animate-fade-in-up"
            style={{ animationDelay: `${kpiBase + 2 * kpiStep}ms` }}
            value={<AnimatedNumber value={kpis.received} format={fmt.usd} />}
            delta={{ value: "+8.1%", direction: "up", positive: true }}
          />
        </DrillableCell>
        <DrillableCell
          onClick={() => navigate("/claims")}
          ariaLabel="View pending accounts receivable claims"
        >
          <KpiCard
            label="Pending AR"
            icon={Clock}
            accent="warning"
            sparkline={monthly.ar}
            className="animate-fade-in-up"
            style={{ animationDelay: `${kpiBase + 3 * kpiStep}ms` }}
            value={
              <AnimatedNumber
                value={kpis.outstandingAr}
                format={(n) => fmt.usd(Math.max(0, n))}
              />
            }
            hint={`${kpis.pending} in queue`}
          />
        </DrillableCell>
        <DrillableCell
          onClick={() => navigate("/claims?status=denied")}
          ariaLabel="View denied claims"
        >
          <KpiCard
            label="Denial rate"
            icon={TrendingDown}
            accent="destructive"
            sparkline={monthly.denialRate}
            className="animate-fade-in-up"
            style={{ animationDelay: `${kpiBase + 4 * kpiStep}ms` }}
            value={
              <AnimatedNumber
                value={kpis.denialRate}
                format={(n) => fmt.pct(n)}
              />
            }
            delta={{ value: "-1.2 pts", direction: "down", positive: true }}
          />
        </DrillableCell>
      </section>

      {/* Activity + Top providers */}
      <section
        className="grid gap-4 lg:grid-cols-3 animate-fade-in-up"
        style={{ animationDelay: `${sectionBase}ms` }}
      >
        <Card className="lg:col-span-2">
          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-3">
            <div>
              <CardTitle className="flex items-center gap-2 text-[14px]">
                <Inbox className="h-3.5 w-3.5 text-muted-foreground" strokeWidth={1.75} />
                Recent activity
              </CardTitle>
              <p className="text-xs text-muted-foreground mt-1">
                Newest submissions, denials, and remittances across all providers.
              </p>
            </div>
            <span className="mono text-[10.5px] uppercase tracking-[0.14em] text-muted-foreground">
              {activity.length} events
            </span>
          </CardHeader>
          <CardContent className="pt-0">
            <ActivityFeed
              items={activity.slice(0, 10)}
              onItemClick={(evt) => {
                // SP21 Task 2.5: route by event kind. claim_* kinds
                // navigate to the matching claim drawer (URL-driven,
                // drawer mounts in Phase 5); provider_added opens the
                // ProviderDrawer. remit_received and any unmapped
                // kind surface a "coming soon" toast so the click
                // still gives feedback until the RemitDrawer lands in
                // Phase 4.
                const url = eventKindToUrl(evt);
                if (url) navigate(url);
                else
                  toast.info(
                    `Drill for ${evt.kind.replace(/_/g, " ")} coming in a later phase.`,
                  );
              }}
            />
          </CardContent>
        </Card>

        <Card>
          <CardHeader className="pb-3">
            <CardTitle className="text-[14px]">Top providers</CardTitle>
            <p className="text-xs text-muted-foreground mt-1">
              Ranked by claim volume, last 6 months.
            </p>
          </CardHeader>
          <CardContent className="pt-0">
            <ul className="space-y-4">
              {topProviders.map((p, i) => (
                <li
                  key={p.npi}
                  onClick={() =>
                    navigate(`/providers?provider=${encodeURIComponent(p.npi)}`)
                  }
                  onKeyDown={(e) => {
                    if (e.key === "Enter")
                      navigate(
                        `/providers?provider=${encodeURIComponent(p.npi)}`
                      );
                  }}
                  role="button"
                  tabIndex={0}
                  aria-label={`View provider ${p.name}`}
                  className="drillable flex items-center gap-3"
                >
                  <div className="h-7 w-7 rounded-md bg-muted/60 ring-1 ring-inset ring-border/40 flex items-center justify-center mono text-[10.5px] text-muted-foreground">
                    {String(i + 1).padStart(2, "0")}
                  </div>
                  <div className="flex-1 min-w-0">
                    <div className="text-[13px] font-medium truncate">{p.name}</div>
                    <div className="mono text-[10.5px] text-muted-foreground">
                      NPI {p.npi}
                    </div>
                  </div>
                  <div className="text-right">
                    <div className="display mono text-[15px]">{fmt.num(p.claimCount)}</div>
                    <div className="mono text-[10.5px] text-muted-foreground">
                      {fmt.usd(p.outstandingAr)} AR
                    </div>
                  </div>
                </li>
              ))}
            </ul>
          </CardContent>
        </Card>
      </section>

      {topDenials.length > 0 ? (
        <section
          className="animate-fade-in-up"
          style={{ animationDelay: `${sectionBase + 90}ms` }}
        >
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="flex items-center gap-2 text-[14px]">
                <AlertCircle
                  className="h-3.5 w-3.5 text-destructive"
                  strokeWidth={1.75}
                />
                Recent denials
              </CardTitle>
              <p className="text-xs text-muted-foreground mt-1">
                Investigate and resubmit where appropriate.
              </p>
            </CardHeader>
            <CardContent className="pt-0">
              <ul className="divide-y divide-border/40">
                {topDenials.map((c) => (
                  <li
                    key={c.id}
                    onClick={() => navigate(`/claims?claim=${encodeURIComponent(c.id)}`)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") navigate(`/claims?claim=${encodeURIComponent(c.id)}`);
                    }}
                    role="button"
                    tabIndex={0}
                    aria-label={`View claim ${c.id}`}
                    className="drillable flex items-start gap-3 py-3 first:pt-0 last:pb-0"
                  >
                    <div className="display mono text-[12.5px] text-muted-foreground pt-0.5 w-24 shrink-0">
                      {c.id}
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="text-[13px]">{c.patientName}</div>
                      <div className="text-[11.5px] text-muted-foreground">
                        {c.denialReason ?? "—"}
                      </div>
                    </div>
                    <div className="text-right shrink-0">
                      <div className="display mono text-[13.5px]">
                        {fmt.usd(c.billedAmount)}
                      </div>
                      <div className="text-[10.5px] text-muted-foreground">
                        {c.payerName}
                      </div>
                    </div>
                  </li>
                ))}
              </ul>
            </CardContent>
          </Card>
        </section>
      ) : null}
    </div>
  );
}
