/**
 * Margin — the ledger, per block and in total.
 *
 * The table scrolls inside its own pane on narrow screens rather than making
 * the page scroll sideways; a card list would lose the column comparison that
 * is the entire value of this view.
 */
import { useQuery } from '@tanstack/react-query';
import { ArrowRight } from 'lucide-react';
import { Link } from 'react-router-dom';
import { compactNumber, get, money, moneyExact, percent } from '@/lib/api';
import { Button, Card, CardContent, CardHeader, CardTitle, EmptyState, Skeleton, Stat } from '@/components/ui';
import { usePageTitle } from '@/lib/title';

interface MarginReport {
  totals: {
    committedGpuHours: number;
    allocatedGpuHours: number;
    idleGpuHours: number;
    utilisation: number;
    costCents: number;
    revenueCents: number;
    grossMarginCents: number;
    grossMarginPct: number | null;
    marginPerAllocatedGpuHourCents: number | null;
  };
  blocks: {
    commitmentId: string;
    name: string;
    gpuType: string;
    gpuCount: number;
    totalGpuHours: number;
    soldGpuHours: number;
    availableGpuHours: number;
    costPerGpuHourCents: number;
    utilisation: number;
    breakEvenPriceCents: number | null;
  }[];
}

export function Margin() {
  usePageTitle('Margin');
  const { data, isLoading, error, refetch } = useQuery({
    queryKey: ['margin'],
    queryFn: () => get<MarginReport>('/api/capacity/margin'),
  });

  if (isLoading) {
    return <div className="flex flex-col gap-4"><Skeleton className="h-16" /><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="Could not load margin" description={error instanceof Error ? error.message : 'The margin ledger is unavailable.'} />
          <Button variant="outline" onClick={() => void refetch()}>Try again</Button>
        </CardContent>
      </Card>
    );
  }
  if (data.blocks.length === 0) {
    return (
      <EmptyState
        title="No capacity to report on"
        description="Margin is computed from capacity commitments and the allocations against them."
      />
    );
  }

  const t = data.totals;

  return (
    <div className="space-y-5 pb-[calc(5.5rem+var(--safe-bottom))] md:pb-0">
      <header>
        <h1 className="text-xl font-semibold tracking-tight sm:text-2xl">Margin</h1>
        <p className="mt-1 max-w-2xl text-sm text-muted">
          Revenue from what we sold, against the full cost of what we bought.
        </p>
      </header>

      <section className="grid grid-cols-2 gap-2 sm:gap-3 xl:grid-cols-4">
        <Stat label="Revenue" value={money(t.revenueCents)} />
        <Stat label="Cost" value={money(t.costCents)} hint="Full commitment" />
        <Stat
          label="Gross margin"
          value={money(t.grossMarginCents)}
          hint={percent(t.grossMarginPct, 1)}
          tone={t.grossMarginCents >= 0 ? 'positive' : 'danger'}
        />
        <Stat
          label="Per sold GPU-hour"
          value={moneyExact(t.marginPerAllocatedGpuHourCents)}
          hint={`${percent(t.utilisation, 1)} of committed hours sold`}
        />
      </section>

      <Card>
        <CardHeader className="flex-row items-center justify-between gap-3 space-y-0">
          <div>
            <CardTitle className="text-base">By commitment</CardTitle>
            <p className="mt-1 text-xs text-muted">Sold ratio describes contracted capacity sold, not workload utilization.</p>
          </div>
          <Link to="/capacity" className="tap inline-flex min-h-11 shrink-0 items-center gap-1 rounded-lg px-3 text-sm font-medium text-accent-fg hover:bg-surface-2">
            Capacity <ArrowRight className="size-4" aria-hidden />
          </Link>
        </CardHeader>
        <CardContent className="px-0 sm:px-0">
          <div className="hidden scroll-x md:block">
            <table className="w-full min-w-[720px] text-sm">
              <thead>
                <tr className="border-b border-border text-left text-xs uppercase tracking-wide text-muted">
                  <th className="px-4 pb-2 font-medium sm:px-5">Commitment</th>
                  <th className="px-4 pb-2 text-right font-medium">Sold</th>
                  <th className="px-4 pb-2 text-right font-medium">Sellable</th>
                  <th className="px-4 pb-2 text-right font-medium">Sold ratio</th>
                  <th className="px-4 pb-2 text-right font-medium">Cost/hr</th>
                  <th className="px-4 pb-2 text-right font-medium sm:px-5">Break even</th>
                </tr>
              </thead>
              <tbody>
                {data.blocks.map((block) => (
                  <tr key={block.commitmentId} className="border-b border-border/60 last:border-0">
                    <td className="px-4 py-3 sm:px-5">
                      <div className="font-medium">{block.name}</div>
                      <div className="text-xs text-muted">
                        {block.gpuCount}× {block.gpuType}
                      </div>
                    </td>
                    <td className="nums px-4 py-3 text-right">
                      {compactNumber(block.soldGpuHours)}
                    </td>
                    <td className="nums px-4 py-3 text-right">
                      {compactNumber(block.availableGpuHours)}
                    </td>
                    <td
                      className={[
                        'nums px-4 py-3 text-right font-medium',
                        block.utilisation < 0.5 ? 'text-warning' : '',
                      ].join(' ')}
                    >
                      {percent(block.utilisation)}
                    </td>
                    <td className="nums px-4 py-3 text-right">
                      {moneyExact(block.costPerGpuHourCents)}
                    </td>
                    {/*
                      A zero break-even means the block's cost is already
                      covered, so any further sale is upside. Printing "$0.00"
                      is technically true and reads like a bug — the same fix
                      already applied on the capacity cards.
                    */}
                    <td className="px-4 py-3 text-right sm:px-5"><BreakEven value={block.breakEvenPriceCents} /></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <div className="grid gap-3 px-4 pb-4 md:hidden">
            {data.blocks.map((block) => (
              <article key={block.commitmentId} className="rounded-xl border border-border p-4">
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <h3 className="break-words font-medium leading-snug">{block.name}</h3>
                    <p className="mt-1 text-xs text-muted">{block.gpuCount}× {block.gpuType}</p>
                  </div>
                  <span className={['nums shrink-0 text-sm font-semibold', block.utilisation < 0.5 ? 'text-warning' : ''].join(' ')}>{percent(block.utilisation)} sold</span>
                </div>
                <dl className="mt-4 grid grid-cols-2 gap-x-4 gap-y-2 text-sm">
                  <dt className="text-muted">Sold capacity</dt><dd className="nums text-right">{compactNumber(block.soldGpuHours)} hrs</dd>
                  <dt className="text-muted">Sellable capacity</dt><dd className="nums text-right">{compactNumber(block.availableGpuHours)} hrs</dd>
                  <dt className="text-muted">Our cost</dt><dd className="nums text-right">{moneyExact(block.costPerGpuHourCents)}/GPU-hr</dd>
                  <dt className="text-muted">Break even</dt><dd className="text-right"><BreakEven value={block.breakEvenPriceCents} /></dd>
                </dl>
              </article>
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

function BreakEven({ value }: { value: number | null }) {
  if (value == null) return <span className="text-muted">Sold out</span>;
  if (value === 0) return <span className="text-positive">Cost covered</span>;
  return <span className="nums">{moneyExact(value)}/GPU-hr</span>;
}
