import { useDeferredValue, useId, useMemo, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  AlertTriangle,
  ArrowRight,
  CalendarClock,
  Check,
  ChevronRight,
  FileCheck2,
  FilePlus2,
  Lock,
  Pencil,
  Plus,
  RefreshCw,
  ShieldCheck,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  ACCOUNT_SIDES,
  CONTRACT_STATUSES,
  CONTRACT_TYPES,
  SLA_KINDS,
  SLA_METRICS,
  type ContractStatus,
  type ContractType,
  type SlaKind,
} from '@pig/core';
import { dateRange, get, money, patch, post, shortDate } from '@/lib/api';
import { usePageTitle } from '@/lib/title';
import { useIdentity } from '@/lib/identity';
import { can, canAny } from '@/lib/permissions';
import {
  Badge,
  Button,
  Card,
  CardContent,
  EmptyState,
  Input,
  Label,
  Section,
  Skeleton,
  Stat,
  cn,
} from '@/components/ui';
import { FormField } from '@/components/ui/form-field';
import { PageHeader } from '@/components/ui/page-header';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet';
import { Switch } from '@/components/ui/switch';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Textarea } from '@/components/ui/textarea';
import { PiggyAskButton } from '@/components/PiggyChat';
import {
  CONTRACT_STATUS_LABELS,
  ContractStatusBadge,
  RenewalBadge,
  type RenewalState,
} from '@/components/status';

type ContractSide = (typeof ACCOUNT_SIDES)[number];

interface ContractRecord {
  id: string;
  accountId: string;
  type: ContractType;
  status: ContractStatus;
  side: ContractSide;
  title: string;
  externalReference: string | null;
  demandDealId: string | null;
  supplyDealId: string | null;
  capacityCommitmentId: string | null;
  parentContractId: string | null;
  contractingPartyName: string | null;
  takeOrPayFloorPct: string | null;
  prepaidPct: string | null;
  terminationTier: string | null;
  assignableOnDefault: boolean;
  assignmentDeadlineBusinessDays: number | null;
  effectiveAt: string | null;
  expiresAt: string | null;
  executedAt: string | null;
  terminatedAt: string | null;
  isAutoRenew: boolean;
  noticeDays: number | null;
  valueCents: number | null;
  currency: string;
  governingLaw: string | null;
  documentUrl: string | null;
  ownerUserId: string | null;
  notes: string | null;
  createdAt: string;
  updatedAt: string;
}

interface SlaRecord {
  id: string;
  contractId: string;
  kind: SlaKind;
  uptimeTargetPct: string | null;
  nodeReplacementHours: number | null;
  mttrHours: number | null;
  supportResponseHours: number | null;
  measurementWindow: string;
  measurementUnit: string;
  remedyType: 'service_credit' | 'fee_abatement' | 'termination_right';
  abatementTriggerValue: number | null;
  abatementTriggerUnit: string | null;
  claimDeadlineValue: number | null;
  claimDeadlineUnit: string;
  creditExpiryMonths: number | null;
  isSoleRemedy: boolean;
  sparePoolObligation: string | null;
  sparePoolScope: string[];
  maintenanceClasses: MaintenanceClass[];
  reasonableEndeavoursDaysPerYear: number | null;
  rcaDeliveryHours: number | null;
  creditSchedule: CreditTier[];
  creditCapPct: string | null;
  exclusions: string | null;
}

interface MetricTarget {
  id: string;
  metric: (typeof SLA_METRICS)[number];
  targetValue: string;
  unit: string | null;
}

interface Obligation {
  id: string;
  contractId: string;
  title: string;
  description: string | null;
  kind: 'renewal_notice' | 'milestone' | 'payment' | 'review' | 'true_up';
  dueAt: string;
  completedAt: string | null;
  ownerUserId: string | null;
}

interface EffectiveTerm {
  value: unknown;
  sourceContractId: string;
  inherited: boolean;
}

interface ContractListRow {
  contract: ContractRecord;
  accountName: string | null;
  renewalNoticeAt: string | null;
  renewalState: RenewalState;
}

interface ContractDetail extends ContractListRow {
  hierarchy: { chain: ContractRecord[]; children: ContractRecord[] };
  effectiveTerms: {
    contract: Record<string, EffectiveTerm>;
    sla: Record<string, EffectiveTerm>;
  };
  sla: SlaRecord | null;
  slaMetrics: MetricTarget[];
  obligations: Obligation[];
}

interface AccountOption {
  id: string;
  name: string;
  side: ContractSide;
}

interface CreditTier {
  belowPct: number;
  creditPct: number;
}

interface MaintenanceClass {
  class: string;
  noticeValue: number;
  noticeUnit: string;
  allowancePerPeriodHours?: number;
  excludedFromUptime: boolean;
}

interface ContractFormState {
  accountId: string;
  type: ContractType;
  status: ContractStatus;
  side: ContractSide;
  title: string;
  externalReference: string;
  parentContractId: string;
  contractingPartyName: string;
  takeOrPayFloorPct: string;
  prepaidPct: string;
  terminationTier: string;
  assignableOnDefault: boolean;
  assignmentDeadlineBusinessDays: string;
  effectiveAt: string;
  expiresAt: string;
  executedAt: string;
  isAutoRenew: boolean;
  noticeDays: string;
  value: string;
  currency: string;
  governingLaw: string;
  documentUrl: string;
  notes: string;
  slaKind: SlaKind;
  uptimeTargetPct: string;
  measurementWindow: string;
  measurementUnit: string;
  remedyType: SlaRecord['remedyType'];
  abatementTriggerValue: string;
  abatementTriggerUnit: string;
  claimDeadlineValue: string;
  claimDeadlineUnit: string;
  creditExpiryMonths: string;
  creditCapPct: string;
  isSoleRemedy: boolean;
  nodeReplacementHours: string;
  mttrHours: string;
  supportResponseHours: string;
  sparePoolObligation: string;
  sparePoolScope: string;
  maintenanceClasses: string;
  reasonableEndeavoursDaysPerYear: string;
  rcaDeliveryHours: string;
  creditSchedule: string;
  exclusions: string;
  metricTargets: string;
}

const TYPE_LABELS: Record<ContractType, string> = {
  msa: 'MSA',
  dpa: 'DPA',
  sla: 'SLA',
  order_form: 'Order form',
  capacity_commitment: 'Capacity commitment',
  nda: 'NDA',
  amendment: 'Amendment',
};

const EMPTY_FORM: ContractFormState = {
  accountId: '',
  type: 'msa',
  status: 'draft',
  side: 'demand',
  title: '',
  externalReference: '',
  parentContractId: '',
  contractingPartyName: '',
  takeOrPayFloorPct: '',
  prepaidPct: '',
  terminationTier: '',
  assignableOnDefault: false,
  assignmentDeadlineBusinessDays: '',
  effectiveAt: '',
  expiresAt: '',
  executedAt: '',
  isAutoRenew: false,
  noticeDays: '',
  value: '',
  currency: 'USD',
  governingLaw: '',
  documentUrl: '',
  notes: '',
  slaKind: 'none',
  uptimeTargetPct: '',
  measurementWindow: 'monthly',
  measurementUnit: 'cluster',
  remedyType: 'service_credit',
  abatementTriggerValue: '',
  abatementTriggerUnit: 'business_days',
  claimDeadlineValue: '',
  claimDeadlineUnit: 'days',
  creditExpiryMonths: '',
  creditCapPct: '',
  isSoleRemedy: true,
  nodeReplacementHours: '',
  mttrHours: '',
  supportResponseHours: '',
  sparePoolObligation: '',
  sparePoolScope: '',
  maintenanceClasses: '',
  reasonableEndeavoursDaysPerYear: '',
  rcaDeliveryHours: '',
  creditSchedule: '',
  exclusions: '',
  metricTargets: '',
};

/**
 * What the server will actually allow, asked once and answered per side.
 *
 * This page shipped without asking at all: every create and save button was
 * enabled for everyone, while `POST /api/contracts` requires `contract:sign`
 * for the *specific* side the paper governs — `ensureSidePermission` in
 * contracts.ts. So a demand-team admin filling in a supply MSA got a filled
 * form, a working Save button and a 403 after typing forty fields. The whole
 * point of the shared permission model is that the button and the endpoint
 * read the same rule; here they were not even asking the same question.
 *
 * `disabled`, never hidden. A control that vanishes teaches nothing; one that
 * is greyed out with a reason tells the reader who to ask.
 */
function useContractSigning() {
  const me = useIdentity();
  const supply = can(me, 'contract:sign', 'supply');
  const demand = can(me, 'contract:sign', 'demand');
  return {
    supply,
    demand,
    any: supply || demand,
    /** `both` is rejected by the server outright, so it is never signable. */
    forSide: (side: ContractSide) => (side === 'supply' ? supply : side === 'demand' ? demand : false),
  };
}

const SIGN_DENIED = 'Signing paper on this side needs the contract:sign permission.';

export function Contracts() {
  usePageTitle('Contracts');
  const me = useIdentity();
  const signing = useContractSigning();
  /*
   * `?contract=<id>` opens straight into that contract's sheet.
   *
   * PIG has no `/contracts/:id` route, and the consequence was that a contract
   * named on another page could not be reached from it at all: the account
   * record page lists a customer's paper by title, status and notice date, and
   * every one of those rows was inert text. Journey-tested, "open the contract
   * this account is on" was impossible — the only way through was the list, a
   * search and a guess.
   *
   * Read once, in a lazy initialiser rather than an effect, so arriving with
   * the parameter opens the sheet on the first paint and closing it does not
   * fight a re-read. The parameter is dropped on close (below) so the sheet
   * does not reopen on a refresh or a Back.
   */
  const [searchParams, setSearchParams] = useSearchParams();
  const [selectedId, setSelectedId] = useState<string | null>(() => searchParams.get('contract'));
  const [editor, setEditor] = useState<'create' | 'edit' | null>(null);
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query.trim().toLocaleLowerCase());
  const [type, setType] = useState<'all' | ContractType>('all');
  const [side, setSide] = useState<'all' | ContractSide>('all');

  const contractsQuery = useQuery({
    queryKey: ['contracts'],
    queryFn: () => get<ContractListRow[]>('/api/contracts'),
  });
  const detailQuery = useQuery({
    queryKey: ['contracts', selectedId],
    queryFn: () => get<ContractDetail>(`/api/contracts/${selectedId}`),
    enabled: Boolean(selectedId),
  });
  const accountsQuery = useQuery({
    queryKey: ['accounts', 'contract-options'],
    queryFn: () => get<AccountOption[]>('/api/accounts'),
  });

  const visible = useMemo(() => {
    const needle = deferredQuery;
    return (contractsQuery.data ?? []).filter(({ contract, accountName }) => {
      if (type !== 'all' && contract.type !== type) return false;
      if (side !== 'all' && contract.side !== side) return false;
      return (
        !needle ||
        contract.title.toLocaleLowerCase().includes(needle) ||
        accountName?.toLocaleLowerCase().includes(needle) ||
        contract.externalReference?.toLocaleLowerCase().includes(needle)
      );
    });
  }, [contractsQuery.data, deferredQuery, side, type]);

  const portfolio = useMemo(() => {
    const rows = contractsQuery.data ?? [];
    return {
      due: rows.filter((row) => row.renewalState === 'due').length,
      governing: rows.filter((row) => !row.contract.parentContractId).length,
      executed: rows.filter((row) => row.contract.status === 'executed').length,
    };
  }, [contractsQuery.data]);
  const filtered = Boolean(query || type !== 'all' || side !== 'all');

  // Every negotiated term on this page is behind `book:read` now. Without it
  // the three queries above all answer 403, so say why rather than rendering
  // three separate network errors.
  if (!canAny(me, 'book:read')) {
    return (
      <div className="space-y-6">
        <PageHeader title="Contracts" />
        <Card>
          <CardContent className="pt-5">
            <EmptyState
              icon={<Lock />}
              title="Contracts are restricted"
              description="Reading negotiated terms needs the book permission. Ask a platform administrator for team membership."
            />
          </CardContent>
        </Card>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <PageHeader
        title="Contracts"
        description="Governing paper, commercial quality, service commitments and the dates that cannot slip."
        actions={
          <Button
            type="button"
            variant="primary"
            disabled={!signing.any}
            title={signing.any ? undefined : SIGN_DENIED}
            onClick={() => {
              setSelectedId(null);
              setEditor('create');
            }}
          >
            <FilePlus2 aria-hidden />
            New contract
          </Button>
        }
      />

      {contractsQuery.data?.length ? (
        <Card
          role="group"
          aria-label="Contract portfolio summary"
          className="grid grid-cols-3 gap-2 p-4 sm:p-5"
        >
          <Stat size="md" surface="inset" label="Governing" value={portfolio.governing} />
          <Stat size="md" surface="inset" label="Executed" value={portfolio.executed} />
          <Stat
            size="md"
            surface="inset"
            label="Notice due"
            value={portfolio.due}
            tone={portfolio.due > 0 ? 'warning' : undefined}
          />
        </Card>
      ) : null}

      {/* No panel around the filters. On a 98% canvas the controls' own
          `bg-surface` already separates them, and a bordered band here read as a
          second card stacked under the portfolio summary. */}
      <div className="grid gap-2 sm:grid-cols-[minmax(0,1fr)_160px_140px]">
        <Input
          aria-label="Search contracts"
          placeholder="Search paper, account or reference"
          value={query}
          onChange={(event) => setQuery(event.target.value)}
        />
        <EnumSelect aria-label="Filter by paper type" value={type} onValueChange={(value) => setType(value as typeof type)}>
          <SelectItem value="all">All paper</SelectItem>
          {CONTRACT_TYPES.map((value) => (
            <SelectItem key={value} value={value}>{TYPE_LABELS[value]}</SelectItem>
          ))}
        </EnumSelect>
        <EnumSelect aria-label="Filter by market side" value={side} onValueChange={(value) => setSide(value as typeof side)}>
          <SelectItem value="all">Both sides</SelectItem>
          <SelectItem value="demand">Demand</SelectItem>
          <SelectItem value="supply">Supply</SelectItem>
        </EnumSelect>
      </div>

      {!contractsQuery.isLoading && !contractsQuery.isError && contractsQuery.data?.length ? (
        <div className="flex min-h-11 flex-wrap items-center justify-between gap-2">
          <p className="text-sm text-muted"><strong className="nums text-fg">{visible.length}</strong> of {contractsQuery.data.length} contracts shown</p>
          {filtered ? <Button className="min-h-11" variant="ghost" onClick={() => { setQuery(''); setType('all'); setSide('all'); }}>Clear filters</Button> : null}
        </div>
      ) : null}

      {contractsQuery.isLoading ? <Skeleton className="h-72" /> : null}
      {contractsQuery.isError ? <Card><CardContent className="pt-5"><EmptyState icon={<AlertTriangle />} title="Contracts unavailable" description={contractsQuery.error.message} action={<Button variant="outline" onClick={() => void contractsQuery.refetch()}><RefreshCw aria-hidden />Try again</Button>} /></CardContent></Card> : null}
      {!contractsQuery.isLoading && !contractsQuery.isError && visible.length === 0 ? (
        <Card>
          <CardContent className="pt-5">
            <EmptyState
              icon={<FileCheck2 />}
              title={contractsQuery.data?.length ? 'No contracts match' : 'No contracts recorded'}
              description={
                contractsQuery.data?.length
                  ? 'Clear a filter to see the rest of the book.'
                  : 'Record the governing MSA first, then attach order forms, SLAs and obligations.'
              }
              action={
                contractsQuery.data?.length ? undefined : (
                  <Button variant="primary" disabled={!signing.any} title={signing.any ? undefined : SIGN_DENIED} onClick={() => setEditor('create')}>Add governing paper</Button>
                )
              }
            />
          </CardContent>
        </Card>
      ) : null}

      {visible.length ? (
        <>
          <Card className="hidden md:block">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead><Label as="span">Paper</Label></TableHead>
                  <TableHead><Label as="span">Counterparty</Label></TableHead>
                  <TableHead><Label as="span">Quality</Label></TableHead>
                  <TableHead><Label as="span">Term</Label></TableHead>
                  <TableHead><Label as="span">Renewal action</Label></TableHead>
                  <TableHead className="w-12"><span className="sr-only">Open</span></TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {visible.map((row) => (
                  <TableRow
                    key={row.contract.id}
                    className="cursor-pointer"
                    tabIndex={0}
                    onClick={() => setSelectedId(row.contract.id)}
                    onKeyDown={(event) => {
                      if (event.key === 'Enter' || event.key === ' ') setSelectedId(row.contract.id);
                    }}
                  >
                    <TableCell>
                      <div className="min-w-0">
                        <div className="flex items-center gap-2">
                          <Badge tone="neutral">{TYPE_LABELS[row.contract.type]}</Badge>
                          {row.contract.parentContractId ? <span className="text-xs text-muted">Child paper</span> : null}
                        </div>
                        <p className="mt-1 max-w-xs truncate font-medium">{row.contract.title}</p>
                      </div>
                    </TableCell>
                    <TableCell>
                      <p className="font-medium">{row.accountName ?? 'Unknown account'}</p>
                      <p className="text-xs capitalize text-muted">{row.contract.side}</p>
                    </TableCell>
                    <TableCell><QualityCell contract={row.contract} /></TableCell>
                    <TableCell className="nums text-sm">
                      <Term contract={row.contract} />
                    </TableCell>
                    <TableCell>
                      <RenewalBadge state={row.renewalState} noticeAt={row.renewalNoticeAt} />
                    </TableCell>
                    <TableCell><ChevronRight aria-hidden /></TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </Card>

          <div className="grid gap-3 md:hidden">
            {visible.map((row) => (
              <button
                type="button"
                key={row.contract.id}
                className="card min-h-[44px] min-w-0 p-4 text-left"
                onClick={() => setSelectedId(row.contract.id)}
              >
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <div className="flex flex-wrap items-center gap-2">
                      <Badge>{TYPE_LABELS[row.contract.type]}</Badge>
                      <ContractStatusBadge status={row.contract.status} />
                      {row.contract.parentContractId ? <Badge tone="neutral">Child paper</Badge> : null}
                    </div>
                    <p className="mt-2 truncate font-medium">{row.contract.title}</p>
                    <p className="mt-0.5 truncate text-sm text-muted">{row.accountName}</p>
                  </div>
                  <ChevronRight className="shrink-0 text-muted" aria-hidden />
                </div>
                <div className="mt-3 grid grid-cols-[1fr_auto] items-end gap-3 border-t border-border pt-3 text-xs text-muted">
                  {/* `capitalize` on the side alone. Applied to the whole line
                      it also title-cased the termination label — "Tier Not
                      Recorded" — which is a different sentence from the one the
                      desktop table shows for the same contract. */}
                  <div><p><span className="capitalize">{row.contract.side}</span> · {terminationLabel(row.contract.terminationTier)}</p><p className="nums mt-1"><Term contract={row.contract} /></p></div>
                  <RenewalBadge state={row.renewalState} noticeAt={row.renewalNoticeAt} />
                </div>
              </button>
            ))}
          </div>
        </>
      ) : null}

      <ContractDetailSheet
        contractId={selectedId}
        detail={detailQuery.data}
        isLoading={detailQuery.isLoading}
        error={detailQuery.error instanceof Error ? detailQuery.error : null}
        onRetry={() => void detailQuery.refetch()}
        onOpenChange={(open) => {
          if (!open) {
            setSelectedId(null);
            setEditor(null);
            // `replace`, so dismissing a sheet that a link opened does not put
            // a second entry in history for the same page.
            if (searchParams.has('contract')) {
              const next = new URLSearchParams(searchParams);
              next.delete('contract');
              setSearchParams(next, { replace: true });
            }
          }
        }}
        onEdit={() => setEditor('edit')}
        editing={editor === 'edit'}
        accounts={accountsQuery.data ?? []}
        contracts={contractsQuery.data ?? []}
        onCancelEdit={() => setEditor(null)}
      />

      <Sheet open={editor === 'create'} onOpenChange={(open) => !open && setEditor(null)}>
        <SheetContent side="right" className="w-full overflow-y-auto sm:max-w-3xl">
          <SheetHeader>
            <SheetTitle>New contract</SheetTitle>
            <SheetDescription>Start with what is evidenced in the paper. Unknown terms can stay blank.</SheetDescription>
          </SheetHeader>
          {/* Open on a side the reader can actually sign. A supply-only admin
              landing on the demand default met a dead Save button on a blank
              form, which reads as breakage rather than as policy. */}
          <ContractEditor
            initial={signing.demand ? EMPTY_FORM : { ...EMPTY_FORM, side: 'supply' }}
            accounts={accountsQuery.data ?? []}
            contracts={contractsQuery.data ?? []}
            onCancel={() => setEditor(null)}
            onSaved={(id) => {
              setEditor(null);
              setSelectedId(id);
            }}
          />
        </SheetContent>
      </Sheet>
    </div>
  );
}

function ContractDetailSheet({
  contractId,
  detail,
  isLoading,
  error,
  onRetry,
  onOpenChange,
  onEdit,
  editing,
  accounts,
  contracts,
  onCancelEdit,
}: {
  contractId: string | null;
  detail?: ContractDetail;
  isLoading: boolean;
  error: Error | null;
  onRetry(): void;
  onOpenChange(open: boolean): void;
  onEdit(): void;
  editing: boolean;
  accounts: AccountOption[];
  contracts: ContractListRow[];
  onCancelEdit(): void;
}) {
  return (
    <Sheet open={Boolean(contractId)} onOpenChange={onOpenChange}>
      <SheetContent side="right" className="w-full overflow-y-auto sm:max-w-3xl">
        {error ? (
          <><SheetHeader><SheetTitle>Contract unavailable</SheetTitle><SheetDescription>The selected paper could not be loaded.</SheetDescription></SheetHeader><div className="mt-6"><EmptyState icon={<AlertTriangle />} title="Could not load contract" description={error.message} action={<Button variant="outline" onClick={onRetry}><RefreshCw aria-hidden />Try again</Button>} /></div></>
        ) : isLoading || !detail ? (
          <>
            <SheetHeader><SheetTitle>Contract</SheetTitle><SheetDescription>Loading contract terms.</SheetDescription></SheetHeader>
            <Skeleton className="mt-6 h-72" />
          </>
        ) : editing ? (
          <>
            <SheetHeader>
              <SheetTitle>Edit {detail.contract.title}</SheetTitle>
              <SheetDescription>Blank fields inherit from parent paper where one governs.</SheetDescription>
            </SheetHeader>
            <ContractEditor
              contractId={detail.contract.id}
              initial={formFromDetail(detail)}
              accounts={accounts}
              contracts={contracts}
              onCancel={onCancelEdit}
              onSaved={onCancelEdit}
            />
          </>
        ) : (
          <ContractDetailView detail={detail} onEdit={onEdit} />
        )}
      </SheetContent>
    </Sheet>
  );
}

function ContractDetailView({ detail, onEdit }: { detail: ContractDetail; onEdit(): void }) {
  const chain = [...detail.hierarchy.chain].reverse();
  // The side of the paper in front of you, not "any side" — editing a supply
  // MSA is authorised on supply, whatever else you may sign.
  const maySign = useContractSigning().forSide(detail.contract.side as ContractSide);
  return (
    <>
      <SheetHeader>
        <div className="flex flex-wrap items-center gap-2 pr-10">
          <Badge>{TYPE_LABELS[detail.contract.type]}</Badge>
          <ContractStatusBadge status={detail.contract.status} />
          <span className="text-xs capitalize text-muted">{detail.contract.side}</span>
        </div>
        <SheetTitle className="pr-10">{detail.contract.title}</SheetTitle>
        <SheetDescription>{detail.accountName ?? 'Unknown counterparty'}</SheetDescription>
      </SheetHeader>

      {chain.length > 1 ? (
        <div className="mt-4 rounded-md bg-surface-2 p-3">
          <Label className="mb-2">Governing hierarchy</Label>
          <div className="flex flex-wrap items-center gap-1.5 text-sm">
            {chain.map((contract, index) => (
              <span key={contract.id} className="flex items-center gap-1.5">
                {index ? <ChevronRight className="text-muted" aria-hidden /> : null}
                <span className={contract.id === detail.contract.id ? 'font-semibold' : 'text-muted'}>
                  {TYPE_LABELS[contract.type]} · {contract.title}
                </span>
              </span>
            ))}
          </div>
          <p className="mt-2 text-xs text-muted">Explicit child terms take precedence; inherited terms retain their source.</p>
        </div>
      ) : null}

      <div className="mt-4 grid gap-2 sm:flex sm:flex-wrap">
        <Button className="min-h-11 w-full sm:w-auto" type="button" variant="primary" disabled={!maySign} title={maySign ? undefined : SIGN_DENIED} onClick={onEdit}>
          <Pencil aria-hidden /> Edit terms
        </Button>
        <PiggyAskButton
          context={{ type: 'contract', id: detail.contract.id, label: detail.contract.title }}
          prompt="Which terms, obligations or dates need attention?"
        />
        {detail.contract.documentUrl ? (
          <Button className="min-h-11 w-full sm:w-auto" type="button" variant="outline" onClick={() => window.open(detail.contract.documentUrl!, '_blank', 'noopener,noreferrer')}>Open document</Button>
        ) : null}
      </div>

      <Tabs defaultValue="summary" className="mt-6">
        {/* `px-2` only: three labels in a 3-column grid overflow their track at
            393px on the primitive's own `px-3`, and a tab row is not worth a
            horizontal scrollbar. */}
        <TabsList className="grid w-full grid-cols-3">
          <TabsTrigger className="px-2" value="summary">Summary</TabsTrigger>
          <TabsTrigger className="px-2" value="sla">Service levels</TabsTrigger>
          <TabsTrigger className="px-2" value="obligations">Obligations {detail.obligations.length}</TabsTrigger>
        </TabsList>

        <TabsContent value="summary" className="flex flex-col gap-6">
          {detail.renewalState === 'due' ? (
            <div className="flex gap-3 rounded-md border border-warning/30 bg-warning/10 p-3 text-sm">
              <AlertTriangle className="shrink-0 text-warning" aria-hidden />
              <div><p className="font-medium">Renewal notice window is open</p><p className="text-muted">Notice was due {shortDate(detail.renewalNoticeAt)}; expiry is {shortDate(detail.contract.expiresAt)}.</p></div>
            </div>
          ) : null}
          <Section title="Commercial quality">
            <TermGrid>
              <EffectiveValue label="Contract value" term={detail.effectiveTerms.contract.valueCents} format={(value) => money(Number(value), String(detail.effectiveTerms.contract.currency?.value ?? 'USD'))} />
              <EffectiveValue label="Take-or-pay floor" term={detail.effectiveTerms.contract.takeOrPayFloorPct} suffix="%" />
              <EffectiveValue label="Prepaid" term={detail.effectiveTerms.contract.prepaidPct} suffix="%" />
              <EffectiveValue label="Termination tier" term={detail.effectiveTerms.contract.terminationTier} format={terminationLabel} />
              <EffectiveValue label="Assignment on default" term={detail.effectiveTerms.contract.assignableOnDefault} format={(value) => value ? 'Permitted' : 'Not permitted'} />
              <EffectiveValue label="Assignment deadline" term={detail.effectiveTerms.contract.assignmentDeadlineBusinessDays} suffix=" business days" />
            </TermGrid>
          </Section>
          <Section title="Term and paper">
            <TermGrid>
              {/*
                One tile, via `Term`, rather than an Effective tile beside an
                Expires tile. `shortDate` drops the year inside the current one,
                so a twelve-month MSA printed "Effective Oct 4, 2025" above
                "Expires Oct 4" — paper that appears to end before it starts.
                The table column already fixed this; the sheet had not.
              */}
              <Stat
                size="sm"
                surface="inset"
                label="Term"
                value={<Term contract={detail.contract} />}
              />
              <Stat size="sm" surface="inset" label="Renewal notice" value={detail.contract.noticeDays == null ? '—' : `${detail.contract.noticeDays} days`} />
              <Stat size="sm" surface="inset" label="Governing law" value={detail.contract.governingLaw ?? '—'} />
              <Stat size="sm" surface="inset" label="Contracting party" value={detail.contract.contractingPartyName ?? detail.accountName ?? '—'} />
              <Stat size="sm" surface="inset" label="Counterparty reference" value={detail.contract.externalReference ?? '—'} />
            </TermGrid>
          </Section>
          {detail.hierarchy.children.length ? (
            <Section title="Paper governed by this contract">
              <div className="flex flex-col gap-2">
                {detail.hierarchy.children.map((child) => (
                  <div key={child.id} className="flex min-h-11 items-center justify-between rounded-md bg-surface-2 px-3 py-2 text-sm">
                    <span><span className="font-medium">{child.title}</span><span className="ml-2 text-muted">{TYPE_LABELS[child.type]}</span></span>
                    <ContractStatusBadge status={child.status} />
                  </div>
                ))}
              </div>
            </Section>
          ) : null}
          {detail.contract.notes ? <Section title="Notes"><p className="whitespace-pre-wrap text-sm text-muted">{detail.contract.notes}</p></Section> : null}
        </TabsContent>

        <TabsContent value="sla" className="flex flex-col gap-6">
          <SlaDetail detail={detail} />
        </TabsContent>

        <TabsContent value="obligations">
          <Obligations detail={detail} />
        </TabsContent>
      </Tabs>
    </>
  );
}

function SlaDetail({ detail }: { detail: ContractDetail }) {
  const terms = detail.effectiveTerms.sla;
  const kind = terms.kind?.value as SlaKind | undefined;
  if (!kind || kind === 'none') {
    return <EmptyState icon={<ShieldCheck />} title="No service commitment recorded" description="This does not mean one exists. Edit the contract only from evidenced paper." />;
  }
  return (
    <>
      <div className="flex items-start justify-between gap-3 rounded-md bg-surface-2 p-4">
        <div><p className="font-medium">{kind === 'negotiated' ? 'Negotiated SLA' : 'Credits policy'}</p><p className="mt-1 text-sm text-muted">{kind === 'negotiated' ? 'A signed, measurable service commitment.' : 'Reliability and credits terms, not an uptime guarantee.'}</p></div>
        <Badge tone={kind === 'negotiated' ? 'positive' : 'warning'}>{kind === 'negotiated' ? 'Committed' : 'Policy only'}</Badge>
      </div>
      <Section title="Measurement and remedy">
        <TermGrid>
          <EffectiveValue label="Uptime target" term={terms.uptimeTargetPct} suffix="%" />
          <EffectiveValue label="Measurement" term={terms.measurementUnit} />
          <EffectiveValue label="Window" term={terms.measurementWindow} />
          <EffectiveValue label="Remedy" term={terms.remedyType} format={humanise} />
          <EffectiveValue label="Credit cap" term={terms.creditCapPct} suffix="% of fees" />
          <EffectiveValue label="Claim deadline" term={terms.claimDeadlineValue} suffix={` ${String(terms.claimDeadlineUnit?.value ?? 'days')}`} />
          <EffectiveValue label="Credit expiry" term={terms.creditExpiryMonths} suffix=" months" />
          <EffectiveValue label="RCA due" term={terms.rcaDeliveryHours} suffix=" hours" />
        </TermGrid>
      </Section>
      {terms.remedyType?.value === 'fee_abatement' ? (
        <div className="rounded-md border border-info/30 bg-info/10 p-3 text-sm">
          <p className="font-medium">Fee abatement trigger</p>
          <p className="mt-1 text-muted">Fees abate after {String(terms.abatementTriggerValue?.value ?? '—')} consecutive {humanise(terms.abatementTriggerUnit?.value)}.</p>
        </div>
      ) : null}
      <Section title="Operational commitments">
        <TermGrid>
          <EffectiveValue label="Node replacement" term={terms.nodeReplacementHours} suffix=" hours" />
          <EffectiveValue label="MTTR" term={terms.mttrHours} suffix=" hours" />
          <EffectiveValue label="Support response" term={terms.supportResponseHours} suffix=" hours" />
          <EffectiveValue label="Reasonable endeavours" term={terms.reasonableEndeavoursDaysPerYear} suffix=" days/year" />
        </TermGrid>
        {Array.isArray(terms.sparePoolScope?.value) && terms.sparePoolScope.value.length ? (
          <div className="mt-3 flex flex-wrap gap-2">{terms.sparePoolScope.value.map((scope) => <Badge key={String(scope)}>{humanise(scope)}</Badge>)}</div>
        ) : null}
      </Section>
      {Array.isArray(terms.creditSchedule?.value) && terms.creditSchedule.value.length ? (
        <Section title="Credit tiers">
          <div className="flex flex-col gap-2">{terms.creditSchedule.value.map((tier: CreditTier) => <div key={`${tier.belowPct}-${tier.creditPct}`} className="flex justify-between rounded-md bg-surface-2 px-3 py-2 text-sm"><span>Below {tier.belowPct}%</span><strong>{tier.creditPct}% credit</strong></div>)}</div>
        </Section>
      ) : null}
      {Array.isArray(terms.maintenanceClasses?.value) && terms.maintenanceClasses.value.length ? (
        <Section title="Maintenance classes">
          <div className="flex flex-col gap-2">{terms.maintenanceClasses.value.map((item: MaintenanceClass) => <div key={item.class} className="rounded-md bg-surface-2 px-3 py-2 text-sm"><div className="flex justify-between gap-2"><strong>{humanise(item.class)}</strong><span className="text-muted">{item.noticeValue} {humanise(item.noticeUnit)} notice</span></div><p className="mt-1 text-xs text-muted">{item.excludedFromUptime ? 'Excluded from uptime calculation' : 'Counts toward uptime'}{item.allowancePerPeriodHours == null ? '' : ` · ${item.allowancePerPeriodHours} hours allowed per period`}</p></div>)}</div>
        </Section>
      ) : null}
      {terms.exclusions?.value ? <Section title="Exclusions"><p className="whitespace-pre-wrap text-sm text-muted">{String(terms.exclusions.value)}</p></Section> : null}
    </>
  );
}

function Obligations({ detail }: { detail: ContractDetail }) {
  const queryClient = useQueryClient();
  const [adding, setAdding] = useState(false);
  const [title, setTitle] = useState('');
  const [kind, setKind] = useState<Obligation['kind']>('renewal_notice');
  const [dueAt, setDueAt] = useState('');
  // Obligations are governed by the same `contract:sign` grant as the paper
  // they hang off — `createObligationMutationDefinition` re-checks the parent
  // contract's side before it inserts.
  const maySign = useContractSigning().forSide(detail.contract.side as ContractSide);
  const save = useMutation({
    mutationFn: () => post<Obligation>(`/api/contracts/${detail.contract.id}/obligations`, { title, kind, dueAt: new Date(dueAt).toISOString() }),
    onSuccess: async () => {
      setAdding(false); setTitle(''); setDueAt('');
      await queryClient.invalidateQueries({ queryKey: ['contracts', detail.contract.id] });
      toast.success('Obligation added');
    },
    onError: (error: Error) => toast.error(error.message),
  });
  const complete = useMutation({
    mutationFn: (obligation: Obligation) => patch<Obligation>(`/api/contracts/${detail.contract.id}/obligations/${obligation.id}`, { completedAt: obligation.completedAt ? null : new Date().toISOString() }),
    onSuccess: async (obligation) => {
      await queryClient.invalidateQueries({ queryKey: ['contracts', detail.contract.id] });
      toast.success(obligation.completedAt ? 'Obligation completed' : 'Obligation reopened');
    },
    onError: (error: Error) => toast.error(error.message),
  });

  return (
    <Section
      title="Dated obligations"
      description="Renewal, payment, review and delivery alarms."
      action={
        <Button type="button" size="sm" variant="outline" disabled={!maySign} title={maySign ? undefined : SIGN_DENIED} onClick={() => setAdding((value) => !value)}><Plus aria-hidden /> Add</Button>
      }
    >
      <div className="flex flex-col gap-2">
      {adding ? (
        <form className="rounded-md border border-border p-3" onSubmit={(event) => { event.preventDefault(); save.mutate(); }}>
          <div className="grid gap-3 sm:grid-cols-2">
            <FormField label="Obligation" className="sm:col-span-2"><Input required value={title} onChange={(event) => setTitle(event.target.value)} placeholder="Send non-renewal notice" /></FormField>
            <FormField label="Kind"><EnumSelect value={kind} onValueChange={(value) => setKind(value as Obligation['kind'])}>{['renewal_notice', 'milestone', 'payment', 'review', 'true_up'].map((value) => <SelectItem key={value} value={value}>{humanise(value)}</SelectItem>)}</EnumSelect></FormField>
            <FormField label="Due"><Input required type="datetime-local" value={dueAt} onChange={(event) => setDueAt(event.target.value)} /></FormField>
          </div>
          {save.isError ? <p className="mt-2 text-sm text-danger">{save.error.message}</p> : null}
          <div className="mt-3 flex justify-end gap-2"><Button type="button" variant="ghost" onClick={() => setAdding(false)}>Cancel</Button><Button type="submit" variant="primary" disabled={save.isPending || !maySign} title={maySign ? undefined : SIGN_DENIED}>Save obligation</Button></div>
        </form>
      ) : null}
      {detail.obligations.length === 0 ? <EmptyState icon={<CalendarClock />} title="No obligations recorded" description="An expiry date alone cannot be acted on. Add the notice, review or true-up deadline." /> : detail.obligations.map((obligation) => {
        const overdue = !obligation.completedAt && new Date(obligation.dueAt) < new Date();
        return <div key={obligation.id} className={cn('flex items-center gap-3 rounded-md border p-3', overdue ? 'border-warning/40' : 'border-border')}><button type="button" disabled={!maySign} title={maySign ? undefined : SIGN_DENIED} className={cn('flex size-11 shrink-0 items-center justify-center rounded-full border disabled:opacity-50', obligation.completedAt ? 'border-positive bg-positive/10 text-positive' : 'border-border')} aria-label={obligation.completedAt ? 'Reopen obligation' : 'Complete obligation'} onClick={() => complete.mutate(obligation)}>{obligation.completedAt ? <Check aria-hidden /> : null}</button><div className="min-w-0 flex-1"><p className={cn('truncate font-medium', obligation.completedAt && 'text-muted line-through')}>{obligation.title}</p><p className={cn('text-xs', overdue ? 'text-warning' : 'text-muted')}>{humanise(obligation.kind)} · {shortDate(obligation.dueAt)}{overdue ? ' · overdue' : ''}</p></div></div>;
      })}
      </div>
    </Section>
  );
}

function ContractEditor({ initial, contractId, accounts, contracts, onCancel, onSaved }: { initial: ContractFormState; contractId?: string; accounts: AccountOption[]; contracts: ContractListRow[]; onCancel(): void; onSaved(id: string): void }) {
  const queryClient = useQueryClient();
  const [form, setForm] = useState(initial);
  const signing = useContractSigning();
  /*
   * Re-evaluated as the side selector changes, because the server does the
   * same: `ensureSidePermission` is checked against the *pending* side of the
   * update, not the stored one. A demand admin retyping a paper's side to
   * supply is refused, so the Save button must go dead the moment they do.
   */
  const maySign = signing.forSide(form.side);
  const set = <Key extends keyof ContractFormState>(key: Key, value: ContractFormState[Key]) => setForm((current) => ({ ...current, [key]: value }));
  const save = useMutation({
    mutationFn: () => {
      const body = formPayload(form);
      return contractId ? patch<ContractRecord>(`/api/contracts/${contractId}`, body) : post<ContractRecord>('/api/contracts', body);
    },
    onSuccess: async (saved) => {
      await Promise.all([
        queryClient.invalidateQueries({ queryKey: ['contracts'] }),
        queryClient.invalidateQueries({ queryKey: ['contracts', saved.id] }),
      ]);
      toast.success(contractId ? 'Contract terms saved' : 'Contract created');
      onSaved(saved.id);
    },
    onError: (error: Error) => toast.error(error.message),
  });
  const parentOptions = contracts.filter(({ contract }) => contract.id !== contractId && contract.accountId === form.accountId && contract.side === form.side);

  return (
    <form className="mt-5 flex flex-col gap-5 pb-6" onSubmit={(event) => { event.preventDefault(); save.mutate(); }}>
      <Section title="Paper and hierarchy">
        <div className="grid gap-3 sm:grid-cols-2">
          <FormField label="Counterparty"><EnumSelect required placeholder="Choose account" value={form.accountId || undefined} onValueChange={(value) => set('accountId', value)}>{accounts.map((account) => <SelectItem key={account.id} value={account.id}>{account.name}</SelectItem>)}</EnumSelect></FormField>
          <FormField label="Market side"><EnumSelect value={form.side} onValueChange={(value) => set('side', value as ContractSide)}>{ACCOUNT_SIDES.filter((value) => value !== 'both').map((value) => <SelectItem key={value} value={value}>{humanise(value)}</SelectItem>)}</EnumSelect></FormField>
          <FormField label="Paper type"><EnumSelect value={form.type} onValueChange={(value) => set('type', value as ContractType)}>{CONTRACT_TYPES.map((value) => <SelectItem key={value} value={value}>{TYPE_LABELS[value]}</SelectItem>)}</EnumSelect></FormField>
          <FormField label="Status"><EnumSelect value={form.status} onValueChange={(value) => set('status', value as ContractStatus)}>{CONTRACT_STATUSES.map((value) => <SelectItem key={value} value={value}>{CONTRACT_STATUS_LABELS[value]}</SelectItem>)}</EnumSelect></FormField>
          <FormField label="Title" className="sm:col-span-2"><Input required value={form.title} onChange={(event) => set('title', event.target.value)} placeholder="Enterprise capacity order form" /></FormField>
          <FormField label="Parent paper" hint="Explicit terms here override its terms."><EnumSelect value={form.parentContractId || '__none'} onValueChange={(value) => set('parentContractId', value === '__none' ? '' : value)}><SelectItem value="__none">No parent</SelectItem>{parentOptions.map(({ contract }) => <SelectItem key={contract.id} value={contract.id}>{TYPE_LABELS[contract.type]} · {contract.title}</SelectItem>)}</EnumSelect></FormField>
          <FormField label="Counterparty reference"><Input value={form.externalReference} onChange={(event) => set('externalReference', event.target.value)} /></FormField>
          <FormField label="Contracting entity"><Input value={form.contractingPartyName} onChange={(event) => set('contractingPartyName', event.target.value)} placeholder="Only where different from account" /></FormField>
          <FormField label="Executed document URL"><Input type="url" value={form.documentUrl} onChange={(event) => set('documentUrl', event.target.value)} placeholder="https://…" /></FormField>
        </div>
      </Section>

      <Section title="Commercial quality" description="These terms make backlog comparable instead of merely large.">
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          <FormField label="Contract value"><Input inputMode="decimal" value={form.value} onChange={(event) => set('value', event.target.value)} placeholder="0.00" /></FormField>
          <FormField label="Currency"><Input maxLength={3} value={form.currency} onChange={(event) => set('currency', event.target.value.toUpperCase())} /></FormField>
          <FormField label="Termination tier"><EnumSelect value={form.terminationTier || '__none'} onValueChange={(value) => set('terminationTier', value === '__none' ? '' : value)}><SelectItem value="__none">Not recorded</SelectItem><SelectItem value="1_prepaid">1 · Prepaid take-or-pay</SelectItem><SelectItem value="2_take_or_pay">2 · Take-or-pay</SelectItem><SelectItem value="3_cancellable">3 · Cancellable</SelectItem></EnumSelect></FormField>
          <FormField label="Take-or-pay floor %"><Input inputMode="decimal" value={form.takeOrPayFloorPct} onChange={(event) => set('takeOrPayFloorPct', event.target.value)} /></FormField>
          <FormField label="Prepaid %"><Input inputMode="decimal" value={form.prepaidPct} onChange={(event) => set('prepaidPct', event.target.value)} /></FormField>
          <FormField label="Assignment deadline"><Input inputMode="numeric" value={form.assignmentDeadlineBusinessDays} onChange={(event) => set('assignmentDeadlineBusinessDays', event.target.value)} placeholder="Business days" /></FormField>
          <ToggleField label="Assignable on default" checked={form.assignableOnDefault} onCheckedChange={(value) => set('assignableOnDefault', value)} />
        </div>
      </Section>

      <Section title="Term and renewal">
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          <FormField label="Effective"><Input type="date" value={form.effectiveAt} onChange={(event) => set('effectiveAt', event.target.value)} /></FormField>
          <FormField label="Expires"><Input type="date" value={form.expiresAt} onChange={(event) => set('expiresAt', event.target.value)} /></FormField>
          <FormField label="Executed"><Input type="date" value={form.executedAt} onChange={(event) => set('executedAt', event.target.value)} /></FormField>
          <FormField label="Notice period"><Input inputMode="numeric" value={form.noticeDays} onChange={(event) => set('noticeDays', event.target.value)} placeholder="Days" /></FormField>
          <FormField label="Governing law"><Input value={form.governingLaw} onChange={(event) => set('governingLaw', event.target.value)} /></FormField>
          <ToggleField label="Auto-renews" checked={form.isAutoRenew} onCheckedChange={(value) => set('isAutoRenew', value)} />
        </div>
      </Section>

      <Section title="Service levels" description="Credits policies are not displayed as negotiated guarantees.">
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          <FormField label="Commitment shape"><EnumSelect value={form.slaKind} onValueChange={(value) => set('slaKind', value as SlaKind)}>{SLA_KINDS.map((value) => <SelectItem key={value} value={value}>{value === 'none' ? 'No commitment' : value === 'credits_policy' ? 'Credits policy' : 'Negotiated SLA'}</SelectItem>)}</EnumSelect></FormField>
          {form.slaKind !== 'none' ? <>
            <FormField label="Uptime target %"><Input inputMode="decimal" value={form.uptimeTargetPct} onChange={(event) => set('uptimeTargetPct', event.target.value)} /></FormField>
            <FormField label="Measurement unit"><Input value={form.measurementUnit} onChange={(event) => set('measurementUnit', event.target.value)} placeholder="cluster, rack, node…" /></FormField>
            <FormField label="Measurement window"><Input value={form.measurementWindow} onChange={(event) => set('measurementWindow', event.target.value)} placeholder="monthly" /></FormField>
            <FormField label="Remedy"><EnumSelect value={form.remedyType} onValueChange={(value) => set('remedyType', value as SlaRecord['remedyType'])}><SelectItem value="service_credit">Service credit</SelectItem><SelectItem value="fee_abatement">Fee abatement</SelectItem><SelectItem value="termination_right">Termination right</SelectItem></EnumSelect></FormField>
            <FormField label="Credit cap %"><Input inputMode="decimal" value={form.creditCapPct} onChange={(event) => set('creditCapPct', event.target.value)} /></FormField>
            {form.remedyType === 'fee_abatement' ? <><FormField label="Abatement trigger"><Input inputMode="numeric" value={form.abatementTriggerValue} onChange={(event) => set('abatementTriggerValue', event.target.value)} /></FormField><FormField label="Trigger unit"><Input value={form.abatementTriggerUnit} onChange={(event) => set('abatementTriggerUnit', event.target.value)} /></FormField></> : null}
            <FormField label="Claim deadline"><Input inputMode="numeric" value={form.claimDeadlineValue} onChange={(event) => set('claimDeadlineValue', event.target.value)} /></FormField>
            <FormField label="Claim deadline unit"><Input value={form.claimDeadlineUnit} onChange={(event) => set('claimDeadlineUnit', event.target.value)} /></FormField>
            <FormField label="Credit expiry months"><Input inputMode="numeric" value={form.creditExpiryMonths} onChange={(event) => set('creditExpiryMonths', event.target.value)} /></FormField>
            <FormField label="Node replacement hours"><Input inputMode="numeric" value={form.nodeReplacementHours} onChange={(event) => set('nodeReplacementHours', event.target.value)} /></FormField>
            <FormField label="MTTR hours"><Input inputMode="numeric" value={form.mttrHours} onChange={(event) => set('mttrHours', event.target.value)} /></FormField>
            <FormField label="Support response hours"><Input inputMode="numeric" value={form.supportResponseHours} onChange={(event) => set('supportResponseHours', event.target.value)} /></FormField>
            <FormField label="RCA delivery hours"><Input inputMode="numeric" value={form.rcaDeliveryHours} onChange={(event) => set('rcaDeliveryHours', event.target.value)} /></FormField>
            <FormField label="Reasonable-endeavours days/year"><Input inputMode="numeric" value={form.reasonableEndeavoursDaysPerYear} onChange={(event) => set('reasonableEndeavoursDaysPerYear', event.target.value)} /></FormField>
            <ToggleField label="Sole remedy" checked={form.isSoleRemedy} onCheckedChange={(value) => set('isSoleRemedy', value)} />
            <FormField label="Spare-pool scope" hint="Comma-separated; include switches when the paper does."><Input value={form.sparePoolScope} onChange={(event) => set('sparePoolScope', event.target.value)} placeholder="compute nodes, network switches" /></FormField>
            <FormField label="Spare-pool obligation" className="sm:col-span-2"><Textarea value={form.sparePoolObligation} onChange={(event) => set('sparePoolObligation', event.target.value)} /></FormField>
            <FormField label="Credit tiers" hint="One per line: below %, credit %." className="sm:col-span-2"><Textarea value={form.creditSchedule} onChange={(event) => set('creditSchedule', event.target.value)} placeholder={'99.9, 10\n99.0, 25'} /></FormField>
            <FormField label="Maintenance classes" hint="One per line: class, notice, unit, allowance hours, excluded yes/no." className="sm:col-span-2"><Textarea value={form.maintenanceClasses} onChange={(event) => set('maintenanceClasses', event.target.value)} placeholder="planned, 7, days, 4, yes" /></FormField>
            <FormField label="Additional metric targets" hint="One per line: metric, target, unit." className="sm:col-span-2"><Textarea value={form.metricTargets} onChange={(event) => set('metricTargets', event.target.value)} placeholder="node_availability_pct, 99, percent" /></FormField>
            <FormField label="Exclusions" className="sm:col-span-2"><Textarea value={form.exclusions} onChange={(event) => set('exclusions', event.target.value)} placeholder="Maintenance, force majeure, customer-caused faults…" /></FormField>
          </> : null}
        </div>
      </Section>

      <FormField label="Internal notes"><Textarea value={form.notes} onChange={(event) => set('notes', event.target.value)} placeholder="Do not use this in place of negotiated terms." /></FormField>
      {save.isError ? <p className="text-sm text-danger">{save.error.message}</p> : null}
      <div className="sticky bottom-0 flex flex-col gap-2 border-t border-border bg-surface/95 py-3 backdrop-blur sm:flex-row sm:justify-end">
        {maySign ? null : (
          <p role="status" className="min-w-0 flex-1 text-sm text-muted sm:self-center">
            You may not sign {humanise(form.side)}-side paper. Change the market side, or ask a
            {form.side === 'supply' ? ' supply' : ' demand'}-team administrator.
          </p>
        )}
        <Button type="button" variant="ghost" onClick={onCancel}>Cancel</Button>
        <Button type="submit" variant="primary" disabled={save.isPending || !maySign} title={maySign ? undefined : SIGN_DENIED}>{save.isPending ? 'Saving…' : contractId ? 'Save terms' : 'Create contract'}</Button>
      </div>
    </form>
  );
}

function formPayload(form: ContractFormState) {
  const optionalNumber = (value: string) => value.trim() === '' ? null : Number(value);
  const optionalDate = (value: string) => value ? new Date(`${value}T00:00:00.000Z`).toISOString() : null;
  const lines = (value: string) => value.split('\n').map((line) => line.trim()).filter(Boolean);
  return {
    accountId: form.accountId,
    type: form.type,
    status: form.status,
    side: form.side,
    title: form.title.trim(),
    externalReference: form.externalReference.trim() || null,
    parentContractId: form.parentContractId || null,
    contractingPartyName: form.contractingPartyName.trim() || null,
    takeOrPayFloorPct: optionalNumber(form.takeOrPayFloorPct),
    prepaidPct: optionalNumber(form.prepaidPct),
    terminationTier: form.terminationTier || null,
    assignableOnDefault: form.assignableOnDefault,
    assignmentDeadlineBusinessDays: optionalNumber(form.assignmentDeadlineBusinessDays),
    effectiveAt: optionalDate(form.effectiveAt),
    expiresAt: optionalDate(form.expiresAt),
    executedAt: optionalDate(form.executedAt),
    isAutoRenew: form.isAutoRenew,
    noticeDays: optionalNumber(form.noticeDays),
    valueCents: form.value.trim() ? Math.round(Number(form.value) * 100) : null,
    currency: form.currency,
    governingLaw: form.governingLaw.trim() || null,
    documentUrl: form.documentUrl.trim() || null,
    notes: form.notes.trim() || null,
    sla: {
      kind: form.slaKind,
      uptimeTargetPct: optionalNumber(form.uptimeTargetPct),
      measurementWindow: form.measurementWindow,
      measurementUnit: form.measurementUnit,
      remedyType: form.remedyType,
      abatementTriggerValue: optionalNumber(form.abatementTriggerValue),
      abatementTriggerUnit: form.abatementTriggerUnit || null,
      claimDeadlineValue: optionalNumber(form.claimDeadlineValue),
      claimDeadlineUnit: form.claimDeadlineUnit,
      creditExpiryMonths: optionalNumber(form.creditExpiryMonths),
      creditCapPct: optionalNumber(form.creditCapPct),
      isSoleRemedy: form.isSoleRemedy,
      nodeReplacementHours: optionalNumber(form.nodeReplacementHours),
      mttrHours: optionalNumber(form.mttrHours),
      supportResponseHours: optionalNumber(form.supportResponseHours),
      sparePoolObligation: form.sparePoolObligation.trim() || null,
      sparePoolScope: form.sparePoolScope.split(',').map((value) => value.trim()).filter(Boolean),
      reasonableEndeavoursDaysPerYear: optionalNumber(form.reasonableEndeavoursDaysPerYear),
      rcaDeliveryHours: optionalNumber(form.rcaDeliveryHours),
      creditSchedule: lines(form.creditSchedule).map((line) => { const [belowPct, creditPct] = line.split(',').map(Number); return { belowPct, creditPct }; }),
      maintenanceClasses: lines(form.maintenanceClasses).map((line) => { const [name, notice, unit, allowance, excluded] = line.split(',').map((value) => value.trim()); return { class: name, noticeValue: Number(notice), noticeUnit: unit, allowancePerPeriodHours: allowance ? Number(allowance) : undefined, excludedFromUptime: (excluded ?? '').toLowerCase() === 'yes' }; }),
      metricTargets: lines(form.metricTargets).map((line) => { const [metric, targetValue, unit] = line.split(',').map((value) => value.trim()); return { metric, targetValue: Number(targetValue), unit: unit || null }; }),
      exclusions: form.exclusions.trim() || null,
    },
  };
}

function formFromDetail(detail: ContractDetail): ContractFormState {
  const contract = detail.contract;
  const sla = detail.sla;
  const dateInput = (value: string | null) => value ? value.slice(0, 10) : '';
  return {
    ...EMPTY_FORM,
    accountId: contract.accountId,
    type: contract.type,
    status: contract.status,
    side: contract.side,
    title: contract.title,
    externalReference: contract.externalReference ?? '',
    parentContractId: contract.parentContractId ?? '',
    contractingPartyName: contract.contractingPartyName ?? '',
    takeOrPayFloorPct: contract.takeOrPayFloorPct ?? '',
    prepaidPct: contract.prepaidPct ?? '',
    terminationTier: contract.terminationTier ?? '',
    assignableOnDefault: contract.assignableOnDefault,
    assignmentDeadlineBusinessDays: contract.assignmentDeadlineBusinessDays?.toString() ?? '',
    effectiveAt: dateInput(contract.effectiveAt), expiresAt: dateInput(contract.expiresAt), executedAt: dateInput(contract.executedAt),
    isAutoRenew: contract.isAutoRenew, noticeDays: contract.noticeDays?.toString() ?? '',
    value: contract.valueCents == null ? '' : (contract.valueCents / 100).toFixed(2), currency: contract.currency,
    governingLaw: contract.governingLaw ?? '', documentUrl: contract.documentUrl ?? '', notes: contract.notes ?? '',
    slaKind: sla?.kind ?? 'none', uptimeTargetPct: sla?.uptimeTargetPct ?? '', measurementWindow: sla?.measurementWindow ?? 'monthly', measurementUnit: sla?.measurementUnit ?? 'cluster', remedyType: sla?.remedyType ?? 'service_credit',
    abatementTriggerValue: sla?.abatementTriggerValue?.toString() ?? '', abatementTriggerUnit: sla?.abatementTriggerUnit ?? 'business_days', claimDeadlineValue: sla?.claimDeadlineValue?.toString() ?? '', claimDeadlineUnit: sla?.claimDeadlineUnit ?? 'days', creditExpiryMonths: sla?.creditExpiryMonths?.toString() ?? '', creditCapPct: sla?.creditCapPct ?? '', isSoleRemedy: sla?.isSoleRemedy ?? true,
    nodeReplacementHours: sla?.nodeReplacementHours?.toString() ?? '', mttrHours: sla?.mttrHours?.toString() ?? '', supportResponseHours: sla?.supportResponseHours?.toString() ?? '', sparePoolObligation: sla?.sparePoolObligation ?? '', sparePoolScope: sla?.sparePoolScope.join(', ') ?? '', reasonableEndeavoursDaysPerYear: sla?.reasonableEndeavoursDaysPerYear?.toString() ?? '', rcaDeliveryHours: sla?.rcaDeliveryHours?.toString() ?? '', exclusions: sla?.exclusions ?? '',
    creditSchedule: sla?.creditSchedule.map((tier) => `${tier.belowPct}, ${tier.creditPct}`).join('\n') ?? '',
    maintenanceClasses: sla?.maintenanceClasses.map((item) => `${item.class}, ${item.noticeValue}, ${item.noticeUnit}, ${item.allowancePerPeriodHours ?? ''}, ${item.excludedFromUptime ? 'yes' : 'no'}`).join('\n') ?? '',
    metricTargets: detail.slaMetrics.map((metric) => `${metric.metric}, ${metric.targetValue}, ${metric.unit ?? ''}`).join('\n'),
  };
}

type EnumSelectProps = React.ComponentProps<typeof Select> & {
  id?: string;
  'aria-label'?: string;
  /** Shown while nothing is chosen. A select whose value is unset otherwise
   *  renders an empty box that reads as a broken control. */
  placeholder?: string;
};

function EnumSelect({ children, id, placeholder, 'aria-label': ariaLabel, ...props }: EnumSelectProps) {
  return <Select {...props}><SelectTrigger id={id} aria-label={ariaLabel}><SelectValue placeholder={placeholder} /></SelectTrigger><SelectContent><SelectGroup>{children}</SelectGroup></SelectContent></Select>;
}

function ToggleField({ label, checked, onCheckedChange }: { label: string; checked: boolean; onCheckedChange(value: boolean): void }) {
  const id = useId();
  return <div className="flex min-h-11 items-center justify-between gap-3 rounded-lg border border-border px-3"><Label as="label" htmlFor={id}>{label}</Label><Switch id={id} checked={checked} onCheckedChange={onCheckedChange} /></div>;
}

/**
 * A pair of term tiles per row.
 *
 * No longer a `<dl>`: `Stat` is the product's one label-and-value tile and it
 * renders divs, so a definition list here would have been a `dl` whose children
 * were not `dt`/`dd` — worse for a screen reader than the plain grid it looks
 * like.
 */
function TermGrid({ children }: { children: React.ReactNode }) { return <div className="grid gap-2 sm:grid-cols-2">{children}</div>; }

/**
 * A term as it applies to this paper, and where it came from.
 *
 * The inheritance marker is the tile's hint rather than a corner chip: "Inherited
 * from governing paper" is the sentence a reader needs when a number they are
 * about to quote was never typed on the contract in front of them.
 */
function EffectiveValue({ label, term, suffix = '', format = String }: { label: string; term?: EffectiveTerm; suffix?: string; format?(value: unknown): React.ReactNode }) {
  return (
    <Stat
      size="sm"
      surface="inset"
      label={label}
      value={term ? <>{format(term.value)}{suffix}</> : '—'}
      hint={term?.inherited ? 'Inherited from governing paper' : undefined}
    />
  );
}

/**
 * Both ends of the paper's term, in one string.
 *
 * `dateRange` rather than two `shortDate`s with an arrow between them. A
 * twelve-month contract expires on the same day of the same month it started,
 * and the year was being suppressed on whichever end happened to fall in the
 * current one — so an MSA running Oct 2025 to Oct 2026 printed "Oct 5, 2025 →
 * Oct 5", which reads as a term that ends before it begins. Paper with no
 * expiry keeps the arrow: "starts here and does not stop" is the fact this
 * column carries for an SLA, and a lone start date would hide it.
 */
function Term({ contract }: { contract: Pick<ContractRecord, 'effectiveAt' | 'expiresAt'> }) {
  if (!contract.effectiveAt || !contract.expiresAt) {
    return (
      <>
        {shortDate(contract.effectiveAt)}{' '}
        <ArrowRight className="mx-1 inline size-3" aria-hidden />{' '}
        {shortDate(contract.expiresAt)}
      </>
    );
  }
  return <>{dateRange(contract.effectiveAt, contract.expiresAt)}</>;
}

function QualityCell({ contract }: { contract: ContractRecord }) {
  return <div><ContractStatusBadge status={contract.status} /><p className="mt-1 text-xs text-muted">{terminationLabel(contract.terminationTier)}</p></div>;
}

function terminationLabel(value: unknown): string {
  return value === '1_prepaid' ? 'Tier 1 · prepaid' : value === '2_take_or_pay' ? 'Tier 2 · take-or-pay' : value === '3_cancellable' ? 'Tier 3 · cancellable' : 'Tier not recorded';
}

/**
 * An underscored enum value as a reader would write it.
 *
 * Sentence case, not title case. Title-casing every word rendered "Renewal
 * Notice" and "Service Credit" beside PIG's own sentence-case copy, and a
 * product that capitalises its nouns in one panel and not the next has two
 * voices.
 */
function humanise(value: unknown): string {
  if (value == null) return '—';
  const words = String(value).replaceAll('_', ' ').trim();
  return words ? `${words.charAt(0).toUpperCase()}${words.slice(1)}` : '—';
}
