import { useMemo, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import type {
  CustomerLifecycleProjection,
  CustomerRelationshipState,
  GrowthFacet,
} from '@pig/core';
import {
  AlertTriangle,
  ArrowUpRight,
  Bot,
  CircleDollarSign,
  Clock3,
  Gauge,
  Server,
  Sparkles,
} from 'lucide-react';
import { Link } from 'react-router-dom';
import { PiggyAskButton } from '@/components/PiggyChat';
import { Badge, Button, Card, CardContent, CardHeader, CardTitle, EmptyState, Skeleton, Stat } from '@/components/ui';
import { compactNumber, get, money, moneyExact, shortDate } from '@/lib/api';
import { usePageTitle } from '@/lib/title';

interface GrowthCustomer {
  account: { id: string; name: string; domain: string | null; customerSegment: string | null; ownerUserId: string | null };
  lifecycle: CustomerLifecycleProjection;
  openDealCount: number;
}

interface GrowthReport {
  rulesetVersion: string;
  computedAt: string;
  customers: GrowthCustomer[];
  customersTruncated: boolean;
  idleSupply: Array<{
    commitmentId: string;
    name: string;
    gpuType: string;
    gpuCount: number;
    startsAt: string;
    endsAt: string;
    soldGpuHours: number;
    heldGpuHours: number;
    availableGpuHours: number;
    idleGpuHours: number;
    idleCostCents: number;
    breakEvenPriceCents: number | null;
  }>;
}

type GrowthView = 'priority' | 'expansion' | 'renewal' | 'risk' | 'idle';

export function Growth() {
  usePageTitle('Growth');
  const [view, setView] = useState<GrowthView>('priority');
  const { data, isLoading, error, refetch } = useQuery({
    queryKey: ['growth'],
    queryFn: () => get<GrowthReport>('/api/growth'),
  });
  const customers = useMemo(() => {
    if (!data) return [];
    if (view === 'expansion') return data.customers.filter((row) => row.lifecycle.facets.includes('expansion_candidate'));
    if (view === 'renewal') return data.customers.filter((row) => row.lifecycle.facets.includes('renewal_due'));
    if (view === 'risk') return data.customers.filter((row) => row.lifecycle.facets.includes('at_risk') || row.lifecycle.facets.includes('data_stale'));
    return data.customers;
  }, [data, view]);

  if (isLoading) return <div className="flex flex-col gap-4"><Skeleton className="h-40" /><div className="grid grid-cols-2 gap-2 xl:grid-cols-4">{Array.from({ length: 4 }).map((_, index) => <Skeleton key={index} className="h-28" />)}</div><Skeleton className="h-80" /></div>;
  if (error || !data) return <Card><CardContent className="flex flex-col items-center gap-4 pt-6"><EmptyState title="Growth intelligence is unavailable" description={error instanceof Error ? error.message : 'The lifecycle projection could not be loaded.'} /><Button variant="outline" onClick={() => void refetch()}>Try again</Button></CardContent></Card>;

  const deployed = data.customers.filter((row) => row.lifecycle.relationshipState === 'deployed').length;
  const expansion = data.customers.filter((row) => row.lifecycle.facets.includes('expansion_candidate')).length;
  const attention = data.customers.filter((row) => row.lifecycle.facets.includes('renewal_due') || row.lifecycle.facets.includes('at_risk')).length;
  const idleCost = data.idleSupply.reduce((sum, row) => sum + row.idleCostCents, 0);

  return (
    <div className="space-y-4 pb-[calc(5.5rem+var(--safe-bottom))] md:space-y-5 md:pb-0">
      <header className="relative overflow-hidden rounded-2xl border border-border bg-surface px-4 py-4 sm:px-7 sm:py-6">
        <div className="absolute -right-16 -top-20 size-56 rounded-full bg-accent/10 blur-3xl" />
        <div className="relative max-w-3xl">
          <div className="mb-2 inline-flex items-center gap-2 rounded-full bg-accent-subtle px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.12em] text-accent-fg"><Sparkles className="size-3.5" aria-hidden />Growth intelligence</div>
          <h1 className="text-xl font-semibold tracking-tight sm:text-3xl">Expand, renew, or protect the right account next.</h1>
          <p className="mt-1.5 max-w-2xl text-sm leading-5 text-muted sm:mt-2 sm:leading-6">Deterministic signals from customer paper, deal activity, and sold or reserved capacity. Attention scores are not win or churn probabilities.</p>
          <p className="mt-2 text-[11px] text-muted sm:mt-3 sm:text-xs">Rules {data.rulesetVersion} · computed {new Date(data.computedAt).toLocaleString()}</p>
        </div>
      </header>

      {data.customersTruncated ? (
        <div className="rounded-xl border border-warning/40 bg-warning/10 px-4 py-3 text-sm text-warning" role="status">
          Showing the 200 most recently updated demand accounts. Narrow the workspace before treating these totals as complete.
        </div>
      ) : null}

      <div role="tablist" aria-label="Growth views" className="-mx-1 flex gap-1 overflow-x-auto px-1 pb-1">
        {([
          ['priority', 'Priority'],
          ['expansion', 'Expansion'],
          ['renewal', 'Renewal'],
          ['risk', 'Risk'],
          ['idle', 'Idle supply'],
        ] as const).map(([value, label]) => (
          <button key={value} role="tab" aria-selected={view === value} onClick={() => setView(value)} className={['tap min-h-11 shrink-0 rounded-lg px-4 text-sm font-medium transition-colors', view === value ? 'bg-surface text-fg shadow-sm ring-1 ring-border' : 'text-muted hover:bg-surface-2'].join(' ')}>{label}</button>
        ))}
      </div>

      <section className="grid grid-cols-2 gap-2 sm:gap-3 xl:grid-cols-4">
        <Stat label="Deployed customers" value={deployed} hint="Active sold capacity" />
        <Stat label="Expansion candidates" value={expansion} hint="Evidence-backed openings" tone={expansion ? 'positive' : 'default'} />
        <Stat label="Renewal or risk" value={attention} hint="Needs a human decision" tone={attention ? 'warning' : 'default'} />
        <Stat label="Idle supply cost" value={money(idleCost)} hint="Paid capacity still unsold" tone={idleCost ? 'danger' : 'default'} />
      </section>

      {view === 'idle' ? <IdleSupply rows={data.idleSupply} /> : (
        customers.length ? (
          <section className="grid gap-3 xl:grid-cols-2">
            {customers.map((customer) => <CustomerCard key={customer.account.id} customer={customer} />)}
          </section>
        ) : <Card><EmptyState icon={<Gauge />} title="No accounts in this view" description="Growth only surfaces a facet when its deterministic evidence threshold is met." /></Card>
      )}
    </div>
  );
}

function CustomerCard({ customer }: { customer: GrowthCustomer }) {
  const { account, lifecycle } = customer;
  return (
    <Card className="overflow-hidden">
      <div className="h-1 bg-gradient-to-r from-accent via-info to-positive" />
      <CardHeader className="gap-3">
        <div className="flex items-start gap-3">
          <div className="flex size-11 shrink-0 items-center justify-center rounded-xl bg-accent-subtle font-semibold text-accent-fg">{account.name.slice(0, 2).toUpperCase()}</div>
          <div className="min-w-0 flex-1"><CardTitle className="break-words text-lg leading-snug">{account.name}</CardTitle><p className="mt-1 truncate text-xs text-muted">{account.domain ?? account.customerSegment?.replaceAll('_', ' ') ?? 'Demand account'}</p></div>
          <div className="text-right" aria-label={`Attention score ${lifecycle.score}`}><div className="nums text-2xl font-semibold">{lifecycle.score}</div><div className="text-[10px] uppercase tracking-wide text-muted">attention</div></div>
        </div>
        <div className="flex flex-wrap gap-1.5"><RelationshipBadge state={lifecycle.relationshipState} />{lifecycle.facets.map((facet) => <FacetBadge key={facet} facet={facet} />)}</div>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="grid grid-cols-3 gap-2 rounded-xl bg-surface-2 p-3 text-center">
          <Metric label="Open deals" value={customer.openDealCount} />
          <Metric label="Sold capacity" value={compactNumber(lifecycle.soldCapacityGpuHours)} />
          <Metric label="Held capacity" value={compactNumber(lifecycle.heldCapacityGpuHours)} />
        </div>
        <div className="space-y-2">
          {lifecycle.signals.slice(0, 2).map((signal) => (
            <div key={`${signal.code}:${signal.sourceRefs.map((ref) => ref.id).join(':')}`} className="flex gap-3 rounded-lg border border-border/70 p-3">
              <span className="nums flex size-8 shrink-0 items-center justify-center rounded-lg bg-surface-2 text-xs font-semibold">+{signal.weight}</span>
              <div className="min-w-0"><p className="text-sm leading-5">{signal.explanation}</p><p className="mt-1 text-[11px] uppercase tracking-wide text-muted">{signal.category} · {signal.sourceRefs.map((ref) => ref.type.replaceAll('_', ' ')).join(', ')}</p></div>
            </div>
          ))}
          {lifecycle.signals.length > 2 ? <p className="px-1 text-xs text-muted">+{lifecycle.signals.length - 2} more evidence signal{lifecycle.signals.length === 3 ? '' : 's'} in the account context</p> : null}
        </div>
        {lifecycle.blockers.length ? <div className="rounded-lg bg-warning/10 p-3 text-sm text-warning"><div className="flex gap-2"><AlertTriangle className="mt-0.5 size-4 shrink-0" aria-hidden /><span>{lifecycle.blockers[0]}</span></div></div> : null}
        <div className="flex flex-wrap gap-2">
          <PiggyAskButton context={{ type: 'account', id: account.id, label: account.name }} prompt="Explain this account's lifecycle score and the highest-value next review. Distinguish facts from inference." label="Ask Piggy" variant="outline" />
          <Link className="tap inline-flex min-h-11 flex-1 items-center justify-center gap-2 rounded-lg px-3 text-sm font-medium hover:bg-surface-2 sm:flex-none" to="/accounts">Open account <ArrowUpRight className="size-4" aria-hidden /></Link>
        </div>
      </CardContent>
    </Card>
  );
}

function IdleSupply({ rows }: { rows: GrowthReport['idleSupply'] }) {
  if (!rows.length) return <Card><EmptyState icon={<Server />} title="No material idle supply" description="No near-term commitment currently clears the idle-capacity threshold." /></Card>;
  return <section className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">{rows.map((row) => (
    <Card key={row.commitmentId}>
      <CardHeader><div className="flex items-start justify-between gap-3"><div><CardTitle>{row.name}</CardTitle><p className="mt-1 text-sm text-muted">{row.gpuCount}× {row.gpuType}</p></div><Badge tone="warning">{money(row.idleCostCents)} idle cost</Badge></div></CardHeader>
      <CardContent className="space-y-4">
        <div className="grid grid-cols-3 gap-2"><Metric label="Sold" value={compactNumber(row.soldGpuHours)} /><Metric label="Held" value={compactNumber(row.heldGpuHours)} /><Metric label="Sellable" value={compactNumber(row.availableGpuHours)} /></div>
        <div className="space-y-1 text-sm"><p className="flex justify-between gap-3"><span className="text-muted">Window</span><span>{shortDate(row.startsAt)} – {shortDate(row.endsAt)}</span></p><p className="flex justify-between gap-3"><span className="text-muted">Break even</span><span>{row.breakEvenPriceCents == null ? 'Sold out' : row.breakEvenPriceCents === 0 ? 'Cost covered' : `${moneyExact(row.breakEvenPriceCents)}/GPU-hr`}</span></p></div>
        <Link className="tap inline-flex min-h-11 w-full items-center justify-center gap-2 rounded-lg border border-border px-4 text-sm font-medium hover:bg-surface-2" to="/capacity">Match this capacity <ArrowUpRight className="size-4" aria-hidden /></Link>
      </CardContent>
    </Card>
  ))}</section>;
}

function RelationshipBadge({ state }: { state: CustomerRelationshipState }) {
  const tone = state === 'deployed' ? 'positive' : state === 'contracted' ? 'info' : state === 'former_customer' ? 'warning' : 'neutral';
  return <Badge tone={tone}>{state.replaceAll('_', ' ')}</Badge>;
}

function FacetBadge({ facet }: { facet: GrowthFacet }) {
  const icon = facet === 'renewal_due' ? <Clock3 aria-hidden /> : facet === 'at_risk' ? <AlertTriangle aria-hidden /> : facet === 'idle_supply_match' ? <Server aria-hidden /> : facet === 'expansion_candidate' ? <CircleDollarSign aria-hidden /> : facet === 'data_stale' ? <Bot aria-hidden /> : null;
  const tone = facet === 'at_risk' ? 'danger' : facet === 'renewal_due' || facet === 'data_stale' ? 'warning' : facet === 'expansion_candidate' ? 'positive' : 'accent';
  return <Badge tone={tone}>{icon}{facet.replaceAll('_', ' ')}</Badge>;
}

function Metric({ label, value }: { label: string; value: string | number }) {
  return <div className="min-w-0"><div className="nums truncate font-semibold">{value}</div><div className="truncate text-[10px] uppercase tracking-wide text-muted">{label}</div></div>;
}
