import { useEffect, useMemo } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  ACCOUNT_SIDES,
  AFFILIATION_KINDS,
  CUSTOMER_SEGMENTS,
  DEMAND_STAGE_LABELS,
  DEMAND_STAGES,
  INTERCONNECT_TYPES,
  PRODUCT_LINES,
  SUPPLIER_TYPES,
  SUPPLY_STAGE_LABELS,
  SUPPLY_STAGES,
  type AccountSide,
} from '@pig/core';
import { LoaderCircle } from 'lucide-react';
import { useForm, type Control, type FieldPath, type FieldValues } from 'react-hook-form';
import { toast } from 'sonner';
import { z } from 'zod';
import { Badge, Input } from '@/components/ui';
import { Button } from '@/components/ui/button';
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Separator } from '@/components/ui/separator';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet';
import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea';
import { ApiError, get, patch, post } from '@/lib/api';
import { can, type PermissionIdentity } from '@/lib/permissions';

export interface AccountRecord {
  id: string;
  name: string;
  domain: string | null;
  website: string | null;
  description: string | null;
  side: AccountSide;
  supplierType: (typeof SUPPLIER_TYPES)[number] | null;
  customerSegment: (typeof CUSTOMER_SEGMENTS)[number] | null;
  country: string | null;
  region: string | null;
  jurisdiction: string | null;
  ultimateParentName: string | null;
  ultimateParentCountry: string | null;
  confidence: string;
  lastActivityAt: string | null;
}

export interface ContactRecord {
  id: string;
  accountId: string | null;
  fullName: string;
  firstName: string | null;
  lastName: string | null;
  title: string | null;
  email: string | null;
  phone: string | null;
  linkedinUrl: string | null;
  twitterHandle: string | null;
  githubHandle: string | null;
  websiteUrl: string | null;
  affiliation: (typeof AFFILIATION_KINDS)[number];
  isDecisionMaker: boolean;
  confidence: string;
  confidenceNote: string | null;
  lastActivityAt: string | null;
}

export interface ContactRow {
  contact: ContactRecord;
  accountName: string | null;
  accountSide: AccountSide | null;
}

export interface DemandDealRecord {
  id: string;
  accountId: string;
  name: string;
  description: string | null;
  productLine: (typeof PRODUCT_LINES)[number];
  stage: (typeof DEMAND_STAGES)[number];
  primaryContactId: string | null;
  acvCents: number | null;
  tcvCents: number | null;
  currency: string;
  termMonths: number | null;
  probability: string | number | null;
  expectedCloseDate: string | null;
  closedReason: string | null;
  msaExecuted: boolean;
  dpaExecuted: boolean;
  parentDealId: string | null;
  updatedAt: string;
}

export interface SupplyDealRecord {
  id: string;
  accountId: string;
  siteId: string | null;
  name: string;
  stage: (typeof SUPPLY_STAGES)[number];
  primaryContactId: string | null;
  gpuType: string | null;
  gpuCount: number | null;
  interconnectType: (typeof INTERCONNECT_TYPES)[number] | null;
  targetCostPerGpuHourCents: number | null;
  termMonths: number | null;
  availableFrom: string | null;
  technicalVerdict: string | null;
  technicalNotes: string | null;
  financialVerdict: string | null;
  financialNotes: string | null;
  rejectionReason: string | null;
  updatedAt: string;
}

interface SheetProps<Record> {
  open: boolean;
  onOpenChange(open: boolean): void;
  record?: Record | null;
  identity?: PermissionIdentity;
}

const optionalEmail = z.string().refine(
  (value) => value === '' || z.string().email().safeParse(value).success,
  'Enter a complete email address or leave it blank.',
);
const optionalUrl = z.string().refine(
  (value) => value === '' || z.string().url().safeParse(value).success,
  'Include the full URL, including https://.',
);
const optionalPositiveNumber = z.string().refine(
  (value) => value === '' || (Number.isFinite(Number(value)) && Number(value) > 0),
  'Enter a number greater than zero or leave it blank.',
);
const optionalNonnegativeNumber = z.string().refine(
  (value) => value === '' || (Number.isFinite(Number(value)) && Number(value) >= 0),
  'Enter zero or a positive number.',
);
const optionalProbability = z.string().refine(
  (value) => value === '' || (Number(value) >= 0 && Number(value) <= 100),
  'Use a percentage from 0 to 100.',
);

const accountFormSchema = z.object({
  name: z.string().trim().min(1, 'Name is required.'),
  domain: z.string(),
  website: optionalUrl,
  description: z.string(),
  side: z.enum(ACCOUNT_SIDES),
  supplierType: z.string(),
  customerSegment: z.string(),
  country: z.string(),
  region: z.string(),
  jurisdiction: z.string(),
  ultimateParentName: z.string(),
  ultimateParentCountry: z.string(),
});
type AccountForm = z.infer<typeof accountFormSchema>;

const contactFormSchema = z.object({
  accountId: z.string().uuid('Select an account.'),
  fullName: z.string().trim().min(1, 'Full name is required.'),
  firstName: z.string(),
  lastName: z.string(),
  title: z.string(),
  email: optionalEmail,
  phone: z.string(),
  linkedinUrl: optionalUrl,
  twitterHandle: z.string(),
  githubHandle: z.string(),
  websiteUrl: optionalUrl,
  affiliation: z.enum(AFFILIATION_KINDS),
  isDecisionMaker: z.boolean(),
  confidenceNote: z.string(),
});
type ContactForm = z.infer<typeof contactFormSchema>;

const demandFormSchema = z.object({
  accountId: z.string().uuid('Select a customer account.'),
  name: z.string().trim().min(1, 'Deal name is required.'),
  description: z.string(),
  productLine: z.enum(PRODUCT_LINES),
  stage: z.enum(DEMAND_STAGES),
  primaryContactId: z.string(),
  acv: optionalNonnegativeNumber,
  tcv: optionalNonnegativeNumber,
  currency: z.string().trim().length(3, 'Use a three-letter currency code.'),
  termMonths: optionalPositiveNumber,
  probability: optionalProbability,
  expectedCloseDate: z.string(),
  closedReason: z.string(),
  msaExecuted: z.boolean(),
  dpaExecuted: z.boolean(),
  parentDealId: z.string(),
});
type DemandForm = z.infer<typeof demandFormSchema>;

const supplyFormSchema = z.object({
  accountId: z.string().uuid('Select a supplier account.'),
  name: z.string().trim().min(1, 'Deal name is required.'),
  stage: z.enum(SUPPLY_STAGES),
  primaryContactId: z.string(),
  gpuType: z.string(),
  gpuCount: optionalPositiveNumber,
  interconnectType: z.string(),
  targetCost: optionalNonnegativeNumber,
  termMonths: optionalPositiveNumber,
  availableFrom: z.string(),
  technicalVerdict: z.string(),
  technicalNotes: z.string(),
  financialVerdict: z.string(),
  financialNotes: z.string(),
  rejectionReason: z.string(),
});
type SupplyForm = z.infer<typeof supplyFormSchema>;

const label = (value: string) => value.replace(/_/g, ' ').replace(/^./, (letter) => letter.toUpperCase());
const blankToNull = (value: string) => value.trim() || null;
const optionalNumber = (value: string) => value === '' ? null : Number(value);
const cents = (value: string) => value === '' ? null : Math.round(Number(value) * 100);
const dollars = (value: number | null | undefined) => value == null ? '' : String(value / 100);
const dateInput = (value: string | null | undefined) => value ? value.slice(0, 10) : '';

function canWriteSide(identity: PermissionIdentity | undefined, side: AccountSide): boolean {
  return (
    (side !== 'supply' && can(identity, 'deal:write', 'demand')) ||
    (side !== 'demand' && can(identity, 'deal:write', 'supply'))
  );
}

function accountDefaults(record?: AccountRecord | null): AccountForm {
  return {
    name: record?.name ?? '',
    domain: record?.domain ?? '',
    website: record?.website ?? '',
    description: record?.description ?? '',
    side: record?.side ?? 'demand',
    supplierType: record?.supplierType ?? '',
    customerSegment: record?.customerSegment ?? '',
    country: record?.country ?? '',
    region: record?.region ?? '',
    jurisdiction: record?.jurisdiction ?? '',
    ultimateParentName: record?.ultimateParentName ?? '',
    ultimateParentCountry: record?.ultimateParentCountry ?? '',
  };
}

export function AccountSheet({ open, onOpenChange, record, identity }: SheetProps<AccountRecord>) {
  const queryClient = useQueryClient();
  const form = useForm<AccountForm>({
    resolver: zodResolver(accountFormSchema),
    defaultValues: accountDefaults(record),
  });

  useEffect(() => {
    if (open) form.reset(accountDefaults(record));
  }, [form, open, record]);

  const save = useMutation({
    mutationFn: (values: AccountForm) => {
      const body = {
        ...values,
        domain: blankToNull(values.domain),
        website: blankToNull(values.website),
        description: blankToNull(values.description),
        supplierType: values.side === 'demand' ? null : blankToNull(values.supplierType),
        customerSegment: values.side === 'supply' ? null : blankToNull(values.customerSegment),
        country: blankToNull(values.country),
        region: blankToNull(values.region),
        jurisdiction: blankToNull(values.jurisdiction),
        ultimateParentName: blankToNull(values.ultimateParentName),
        ultimateParentCountry: blankToNull(values.ultimateParentCountry),
      };
      return record ? patch<AccountRecord>(`/api/accounts/${record.id}`, body) : post<AccountRecord>('/api/accounts', body);
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['accounts'] });
      toast.success(record ? 'Account updated' : 'Account created');
      onOpenChange(false);
    },
    onError: (error) => toast.error(errorMessage(error)),
  });

  const side = form.watch('side');
  return (
    <RecordSheet open={open} onOpenChange={onOpenChange} category="Relationship" title={record ? 'Edit account' : 'New account'} description="Keep the commercial side explicit. It controls which team can work the record and where its deals belong.">
      <Form {...form}>
        <form className="flex min-h-0 flex-1 flex-col" onSubmit={form.handleSubmit((values) => save.mutate(values))}>
          <SheetBody>
            <FieldGrid>
              <TextField control={form.control} name="name" label="Account name" placeholder="Acme AI" className="sm:col-span-2" />
              <SelectField control={form.control} name="side" label="Commercial side" options={ACCOUNT_SIDES.map((value) => ({ value, label: label(value), disabled: !canWriteSide(identity, value) }))} />
              <TextField control={form.control} name="domain" label="Domain" placeholder="acme.ai" />
              {side !== 'demand' ? <SelectField control={form.control} name="supplierType" label="Supplier type" optional options={SUPPLIER_TYPES.map((value) => ({ value, label: label(value) }))} /> : null}
              {side !== 'supply' ? <SelectField control={form.control} name="customerSegment" label="Customer segment" optional options={CUSTOMER_SEGMENTS.map((value) => ({ value, label: label(value) }))} /> : null}
              <TextField control={form.control} name="website" label="Website" placeholder="https://acme.ai" className="sm:col-span-2" />
              <TextAreaField control={form.control} name="description" label="Relationship context" placeholder="What they build, what they buy or sell, and why the relationship matters." className="sm:col-span-2" />
            </FieldGrid>
            <Section title="Commercial geography" description="Headquarters and legal jurisdiction are separate because export controls and data residency attach differently.">
              <FieldGrid>
                <TextField control={form.control} name="country" label="Headquarters country" />
                <TextField control={form.control} name="region" label="Region" />
                <TextField control={form.control} name="jurisdiction" label="Legal jurisdiction" className="sm:col-span-2" />
              </FieldGrid>
            </Section>
            <Section title="Ultimate ownership" description="Only enter ownership you can substantiate; the compliance engine must not infer it from headquarters.">
              <FieldGrid>
                <TextField control={form.control} name="ultimateParentName" label="Ultimate parent" />
                <TextField control={form.control} name="ultimateParentCountry" label="Parent country" />
              </FieldGrid>
            </Section>
          </SheetBody>
          <SheetActions pending={save.isPending} onCancel={() => onOpenChange(false)} label={record ? 'Save account' : 'Create account'} />
        </form>
      </Form>
    </RecordSheet>
  );
}

function contactDefaults(record?: ContactRecord | null, accountId?: string): ContactForm {
  return {
    accountId: record?.accountId ?? accountId ?? '',
    fullName: record?.fullName ?? '',
    firstName: record?.firstName ?? '',
    lastName: record?.lastName ?? '',
    title: record?.title ?? '',
    email: record?.email ?? '',
    phone: record?.phone ?? '',
    linkedinUrl: record?.linkedinUrl ?? '',
    twitterHandle: record?.twitterHandle ?? '',
    githubHandle: record?.githubHandle ?? '',
    websiteUrl: record?.websiteUrl ?? '',
    affiliation: record?.affiliation ?? 'unknown',
    isDecisionMaker: record?.isDecisionMaker ?? false,
    confidenceNote: record?.confidenceNote ?? '',
  };
}

export function ContactSheet({ open, onOpenChange, record, identity, defaultAccountId }: SheetProps<ContactRecord> & { defaultAccountId?: string }) {
  const queryClient = useQueryClient();
  const { data: accountsData } = useQuery({
    queryKey: ['accounts', 'all-record-options'],
    queryFn: () => get<AccountRecord[]>('/api/accounts'),
    enabled: open,
  });
  const writableAccounts = useMemo(() => (accountsData ?? []).filter((account) => canWriteSide(identity, account.side)), [accountsData, identity]);
  const form = useForm<ContactForm>({ resolver: zodResolver(contactFormSchema), defaultValues: contactDefaults(record, defaultAccountId) });
  useEffect(() => {
    if (open) form.reset(contactDefaults(record, defaultAccountId));
  }, [defaultAccountId, form, open, record]);

  const save = useMutation({
    mutationFn: (values: ContactForm) => {
      const body = {
        ...values,
        firstName: blankToNull(values.firstName), lastName: blankToNull(values.lastName), title: blankToNull(values.title),
        email: blankToNull(values.email), phone: blankToNull(values.phone), linkedinUrl: blankToNull(values.linkedinUrl),
        twitterHandle: blankToNull(values.twitterHandle), githubHandle: blankToNull(values.githubHandle), websiteUrl: blankToNull(values.websiteUrl),
        confidenceNote: blankToNull(values.confidenceNote),
      };
      return record ? patch<ContactRecord>(`/api/contacts/${record.id}`, body) : post<ContactRecord>('/api/contacts', body);
    },
    onSuccess: async () => {
      await Promise.all([
        queryClient.invalidateQueries({ queryKey: ['contacts'] }),
        queryClient.invalidateQueries({ queryKey: ['accounts'] }),
      ]);
      toast.success(record ? 'Contact updated' : 'Contact created');
      onOpenChange(false);
    },
    onError: (error) => toast.error(errorMessage(error)),
  });

  return (
    <RecordSheet open={open} onOpenChange={onOpenChange} category="Person" title={record ? 'Edit contact' : 'New contact'} description="Record only what is known. PIG never guesses a real person’s address or employment relationship.">
      <Form {...form}>
        <form className="flex min-h-0 flex-1 flex-col" onSubmit={form.handleSubmit((values) => save.mutate(values))}>
          <SheetBody>
            <FieldGrid>
              <SelectField control={form.control} name="accountId" label="Account" className="sm:col-span-2" options={writableAccounts.map((account) => ({ value: account.id, label: `${account.name} · ${label(account.side)}` }))} />
              <TextField control={form.control} name="fullName" label="Full name" className="sm:col-span-2" />
              <TextField control={form.control} name="firstName" label="First name" />
              <TextField control={form.control} name="lastName" label="Last name" />
              <TextField control={form.control} name="title" label="Title" />
              <SelectField control={form.control} name="affiliation" label="Affiliation" options={AFFILIATION_KINDS.map((value) => ({ value, label: label(value) }))} />
              <TextField control={form.control} name="email" label="Email" type="email" description="Leave blank unless the address is sourced or provided. Never infer it from a name and domain." className="sm:col-span-2" />
              <TextField control={form.control} name="phone" label="Phone" />
              <SwitchField control={form.control} name="isDecisionMaker" label="Decision maker" description="They can materially approve or block this relationship." />
            </FieldGrid>
            <Section title="Public profiles">
              <FieldGrid>
                <TextField control={form.control} name="linkedinUrl" label="LinkedIn URL" className="sm:col-span-2" />
                <TextField control={form.control} name="twitterHandle" label="X / Twitter handle" />
                <TextField control={form.control} name="githubHandle" label="GitHub handle" />
                <TextField control={form.control} name="websiteUrl" label="Website URL" className="sm:col-span-2" />
              </FieldGrid>
            </Section>
            <TextAreaField control={form.control} name="confidenceNote" label="Provenance note" description="Use this when the relationship or details need qualification." />
          </SheetBody>
          <SheetActions pending={save.isPending} onCancel={() => onOpenChange(false)} label={record ? 'Save contact' : 'Create contact'} />
        </form>
      </Form>
    </RecordSheet>
  );
}

function demandDefaults(record?: DemandDealRecord | null): DemandForm {
  return {
    accountId: record?.accountId ?? '', name: record?.name ?? '', description: record?.description ?? '',
    productLine: record?.productLine ?? 'compute_reserved', stage: record?.stage ?? 'qualification',
    primaryContactId: record?.primaryContactId ?? '', acv: dollars(record?.acvCents), tcv: dollars(record?.tcvCents),
    currency: record?.currency ?? 'USD', termMonths: record?.termMonths == null ? '' : String(record.termMonths),
    probability: record?.probability == null ? '' : String(Number(record.probability) * 100), expectedCloseDate: dateInput(record?.expectedCloseDate),
    closedReason: record?.closedReason ?? '', msaExecuted: record?.msaExecuted ?? false, dpaExecuted: record?.dpaExecuted ?? false,
    parentDealId: record?.parentDealId ?? '',
  };
}

export function DemandDealSheet({ open, onOpenChange, record }: SheetProps<DemandDealRecord>) {
  const queryClient = useQueryClient();
  const { data: accountData } = useQuery({ queryKey: ['accounts', 'demand-record-options'], queryFn: () => get<AccountRecord[]>('/api/accounts?side=demand'), enabled: open });
  const { data: contactRows } = useQuery({ queryKey: ['contacts', 'demand-record-options'], queryFn: () => get<ContactRow[]>('/api/contacts'), enabled: open });
  const { data: board } = useQuery({ queryKey: ['/api/deals/demand'], queryFn: () => get<{ deals: { deal: DemandDealRecord }[] }>('/api/deals/demand'), enabled: open });
  const form = useForm<DemandForm>({ resolver: zodResolver(demandFormSchema), defaultValues: demandDefaults(record) });
  useEffect(() => { if (open) form.reset(demandDefaults(record)); }, [form, open, record]);
  const accountId = form.watch('accountId');
  const contactOptions = (contactRows ?? []).filter((row) => row.contact.accountId === accountId);
  const parentOptions = (board?.deals ?? []).filter((row) => row.deal.accountId === accountId && row.deal.id !== record?.id);

  const save = useMutation({
    mutationFn: (values: DemandForm) => {
      const body = {
        accountId: values.accountId, name: values.name, description: blankToNull(values.description), productLine: values.productLine, stage: values.stage,
        primaryContactId: blankToNull(values.primaryContactId), acvCents: cents(values.acv), tcvCents: cents(values.tcv), currency: values.currency.toUpperCase(),
        termMonths: optionalNumber(values.termMonths), probability: values.probability === '' ? null : Number(values.probability) / 100,
        expectedCloseDate: blankToNull(values.expectedCloseDate), closedReason: blankToNull(values.closedReason), msaExecuted: values.msaExecuted,
        dpaExecuted: values.dpaExecuted, parentDealId: blankToNull(values.parentDealId),
      };
      return record ? patch<DemandDealRecord>(`/api/deals/demand/${record.id}`, body) : post<DemandDealRecord>('/api/deals/demand', body);
    },
    onSuccess: async () => {
      await Promise.all([queryClient.invalidateQueries({ queryKey: ['/api/deals/demand'] }), queryClient.invalidateQueries({ queryKey: ['accounts'] })]);
      toast.success(record ? 'Demand deal updated' : 'Demand deal created'); onOpenChange(false);
    },
    onError: (error) => toast.error(errorMessage(error)),
  });

  return (
    <RecordSheet open={open} onOpenChange={onOpenChange} category="Demand · sell-side" title={record ? 'Edit demand deal' : 'New demand deal'} description="Capture the commercial case and paper state. Capacity requirements remain separate so the matcher can reason about the technical shape.">
      <Form {...form}>
        <form className="flex min-h-0 flex-1 flex-col" onSubmit={form.handleSubmit((values) => save.mutate(values))}>
          <SheetBody>
            <FieldGrid>
              <SelectField control={form.control} name="accountId" label="Customer account" className="sm:col-span-2" options={(accountData ?? []).map((account) => ({ value: account.id, label: account.name }))} />
              <TextField control={form.control} name="name" label="Deal name" className="sm:col-span-2" />
              <SelectField control={form.control} name="productLine" label="Product line" options={PRODUCT_LINES.map((value) => ({ value, label: label(value) }))} />
              <SelectField control={form.control} name="stage" label="Stage" options={DEMAND_STAGES.map((value) => ({ value, label: DEMAND_STAGE_LABELS[value] }))} />
              <SelectField control={form.control} name="primaryContactId" label="Primary contact" optional className="sm:col-span-2" options={contactOptions.map((row) => ({ value: row.contact.id, label: `${row.contact.fullName}${row.contact.title ? ` · ${row.contact.title}` : ''}` }))} />
              <TextAreaField control={form.control} name="description" label="Deal context" className="sm:col-span-2" />
            </FieldGrid>
            <Section title="Commercials" description="Money is converted to integer cents at the API boundary; probability stays independent of stage.">
              <FieldGrid>
                <TextField control={form.control} name="acv" label="ACV" inputMode="decimal" prefix="$" />
                <TextField control={form.control} name="tcv" label="TCV" inputMode="decimal" prefix="$" />
                <TextField control={form.control} name="currency" label="Currency" maxLength={3} />
                <TextField control={form.control} name="termMonths" label="Term (months)" inputMode="numeric" />
                <TextField control={form.control} name="probability" label="Probability (%)" inputMode="decimal" />
                <TextField control={form.control} name="expectedCloseDate" label="Expected close" type="date" />
              </FieldGrid>
            </Section>
            <Section title="Paper and continuity" description="Legal clears early in this market. These flags remain visible after the deal advances.">
              <FieldGrid>
                <SwitchField control={form.control} name="msaExecuted" label="MSA executed" />
                <SwitchField control={form.control} name="dpaExecuted" label="DPA executed" />
                <SelectField control={form.control} name="parentDealId" label="Parent deal" optional className="sm:col-span-2" options={parentOptions.map((row) => ({ value: row.deal.id, label: row.deal.name }))} />
                <TextAreaField control={form.control} name="closedReason" label="Closed reason" description="Record why a deal was won or lost; leave blank while it is open." className="sm:col-span-2" />
              </FieldGrid>
            </Section>
          </SheetBody>
          <SheetActions pending={save.isPending} onCancel={() => onOpenChange(false)} label={record ? 'Save demand deal' : 'Create demand deal'} />
        </form>
      </Form>
    </RecordSheet>
  );
}

function supplyDefaults(record?: SupplyDealRecord | null): SupplyForm {
  return {
    accountId: record?.accountId ?? '', name: record?.name ?? '', stage: record?.stage ?? 'sourced', primaryContactId: record?.primaryContactId ?? '',
    gpuType: record?.gpuType ?? '', gpuCount: record?.gpuCount == null ? '' : String(record.gpuCount), interconnectType: record?.interconnectType ?? '',
    targetCost: dollars(record?.targetCostPerGpuHourCents), termMonths: record?.termMonths == null ? '' : String(record.termMonths), availableFrom: dateInput(record?.availableFrom),
    technicalVerdict: record?.technicalVerdict ?? '', technicalNotes: record?.technicalNotes ?? '', financialVerdict: record?.financialVerdict ?? '',
    financialNotes: record?.financialNotes ?? '', rejectionReason: record?.rejectionReason ?? '',
  };
}

export function SupplyDealSheet({ open, onOpenChange, record }: SheetProps<SupplyDealRecord>) {
  const queryClient = useQueryClient();
  const { data: accountData } = useQuery({ queryKey: ['accounts', 'supply-record-options'], queryFn: () => get<AccountRecord[]>('/api/accounts?side=supply'), enabled: open });
  const { data: contactRows } = useQuery({ queryKey: ['contacts', 'supply-record-options'], queryFn: () => get<ContactRow[]>('/api/contacts'), enabled: open });
  const form = useForm<SupplyForm>({ resolver: zodResolver(supplyFormSchema), defaultValues: supplyDefaults(record) });
  useEffect(() => { if (open) form.reset(supplyDefaults(record)); }, [form, open, record]);
  const accountId = form.watch('accountId');
  const contactOptions = (contactRows ?? []).filter((row) => row.contact.accountId === accountId);

  const save = useMutation({
    mutationFn: (values: SupplyForm) => {
      const body = {
        accountId: values.accountId, name: values.name, stage: values.stage, primaryContactId: blankToNull(values.primaryContactId), siteId: record?.siteId ?? null,
        gpuType: blankToNull(values.gpuType), gpuCount: optionalNumber(values.gpuCount), interconnectType: blankToNull(values.interconnectType),
        targetCostPerGpuHourCents: cents(values.targetCost), termMonths: optionalNumber(values.termMonths), availableFrom: blankToNull(values.availableFrom),
        technicalVerdict: blankToNull(values.technicalVerdict), technicalNotes: blankToNull(values.technicalNotes), financialVerdict: blankToNull(values.financialVerdict),
        financialNotes: blankToNull(values.financialNotes), rejectionReason: blankToNull(values.rejectionReason),
      };
      return record ? patch<SupplyDealRecord>(`/api/deals/supply/${record.id}`, body) : post<SupplyDealRecord>('/api/deals/supply', body);
    },
    onSuccess: async () => {
      await Promise.all([queryClient.invalidateQueries({ queryKey: ['/api/deals/supply'] }), queryClient.invalidateQueries({ queryKey: ['accounts'] })]);
      toast.success(record ? 'Supply deal updated' : 'Supply deal created'); onOpenChange(false);
    },
    onError: (error) => toast.error(errorMessage(error)),
  });

  return (
    <RecordSheet open={open} onOpenChange={onOpenChange} category="Supply · buy-side" title={record ? 'Edit supply deal' : 'New supply deal'} description="Qualify the capacity and economics independently. A supplier relationship is not interchangeable with a customer opportunity.">
      <Form {...form}>
        <form className="flex min-h-0 flex-1 flex-col" onSubmit={form.handleSubmit((values) => save.mutate(values))}>
          <SheetBody>
            <FieldGrid>
              <SelectField control={form.control} name="accountId" label="Supplier account" className="sm:col-span-2" options={(accountData ?? []).map((account) => ({ value: account.id, label: account.name }))} />
              <TextField control={form.control} name="name" label="Deal name" className="sm:col-span-2" />
              <SelectField control={form.control} name="stage" label="Stage" options={SUPPLY_STAGES.map((value) => ({ value, label: SUPPLY_STAGE_LABELS[value] }))} />
              <SelectField control={form.control} name="primaryContactId" label="Primary contact" optional options={contactOptions.map((row) => ({ value: row.contact.id, label: row.contact.fullName }))} />
            </FieldGrid>
            <Section title="Capacity on offer" description="These terms describe the opportunity, not booked inventory. A commitment is created only after paper is executed.">
              <FieldGrid>
                <TextField control={form.control} name="gpuType" label="GPU type" placeholder="H100_80GB" />
                <TextField control={form.control} name="gpuCount" label="GPU count" inputMode="numeric" />
                <SelectField control={form.control} name="interconnectType" label="Interconnect" optional options={INTERCONNECT_TYPES.map((value) => ({ value, label: value }))} />
                <TextField control={form.control} name="targetCost" label="Target $ / GPU-hr" inputMode="decimal" prefix="$" />
                <TextField control={form.control} name="termMonths" label="Term (months)" inputMode="numeric" />
                <TextField control={form.control} name="availableFrom" label="Available from" type="date" />
              </FieldGrid>
            </Section>
            <Section title="Two-key diligence" description="Technical fitness and financial clearance are independent decisions. Record each verdict in its own voice.">
              <FieldGrid>
                <TextField control={form.control} name="technicalVerdict" label="Technical verdict" placeholder="Passed, conditional, blocked…" />
                <TextField control={form.control} name="financialVerdict" label="Financial verdict" placeholder="Passed, conditional, blocked…" />
                <TextAreaField control={form.control} name="technicalNotes" label="Technical notes" />
                <TextAreaField control={form.control} name="financialNotes" label="Financial notes" />
              </FieldGrid>
            </Section>
            <TextAreaField control={form.control} name="rejectionReason" label="Rejection reason" description="Rejections teach the sourcing team. Leave blank unless the deal is rejected." />
          </SheetBody>
          <SheetActions pending={save.isPending} onCancel={() => onOpenChange(false)} label={record ? 'Save supply deal' : 'Create supply deal'} />
        </form>
      </Form>
    </RecordSheet>
  );
}

function RecordSheet({ open, onOpenChange, category, title, description, children }: { open: boolean; onOpenChange(open: boolean): void; category: string; title: string; description: string; children: React.ReactNode }) {
  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className="flex h-full w-full flex-col gap-0 overflow-hidden border-border p-0 sm:max-w-xl">
        <SheetHeader className="shrink-0 gap-1 px-5 pb-4 pt-5 pr-14 text-left sm:px-6 sm:pr-14">
          <Badge className="mb-1 w-fit" tone="neutral">{category}</Badge>
          <SheetTitle>{title}</SheetTitle>
          <SheetDescription>{description}</SheetDescription>
        </SheetHeader>
        <Separator />
        {children}
      </SheetContent>
    </Sheet>
  );
}

function SheetBody({ children }: { children: React.ReactNode }) {
  return <div className="flex min-h-0 flex-1 flex-col gap-7 overflow-y-auto overscroll-contain px-5 py-5 sm:px-6">{children}</div>;
}

function SheetActions({ pending, onCancel, label: actionLabel }: { pending: boolean; onCancel(): void; label: string }) {
  return (
    <>
      <Separator />
      <div className="flex shrink-0 flex-col-reverse gap-2 px-5 pb-[calc(1rem+var(--safe-bottom))] pt-4 sm:flex-row sm:justify-end sm:px-6">
        <Button type="button" variant="outline" className="h-11" onClick={onCancel}>Cancel</Button>
        <Button type="submit" className="h-11" disabled={pending}>
          {pending ? <LoaderCircle data-icon="inline-start" className="animate-spin" aria-hidden /> : null}
          {pending ? 'Saving…' : actionLabel}
        </Button>
      </div>
    </>
  );
}

function FieldGrid({ children }: { children: React.ReactNode }) {
  return <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">{children}</div>;
}

function Section({ title, description, children }: { title: string; description?: string; children: React.ReactNode }) {
  return (
    <section className="flex flex-col gap-4 border-t border-border pt-6">
      <div className="flex flex-col gap-1">
        <h3 className="text-sm font-semibold">{title}</h3>
        {description ? <p className="text-xs leading-relaxed text-muted-foreground">{description}</p> : null}
      </div>
      {children}
    </section>
  );
}

function TextField<T extends FieldValues>({ control, name, label: fieldLabel, description, className, prefix, ...inputProps }: { control: Control<T>; name: FieldPath<T>; label: string; description?: string; className?: string; prefix?: string } & Omit<React.ComponentProps<typeof Input>, 'name' | 'value' | 'defaultValue'>) {
  return (
    <FormField control={control} name={name} render={({ field }) => (
      <FormItem className={className}>
        <FormLabel>{fieldLabel}</FormLabel>
        <FormControl><Input {...field} {...inputProps} value={String(field.value ?? '')} placeholder={inputProps.placeholder ?? prefix} /></FormControl>
        {description ? <FormDescription>{description}</FormDescription> : null}
        <FormMessage />
      </FormItem>
    )} />
  );
}

function TextAreaField<T extends FieldValues>({ control, name, label: fieldLabel, description, className, placeholder }: { control: Control<T>; name: FieldPath<T>; label: string; description?: string; className?: string; placeholder?: string }) {
  return (
    <FormField control={control} name={name} render={({ field }) => (
      <FormItem className={className}>
        <FormLabel>{fieldLabel}</FormLabel>
        <FormControl><Textarea {...field} value={String(field.value ?? '')} placeholder={placeholder} className="min-h-24 resize-y" /></FormControl>
        {description ? <FormDescription>{description}</FormDescription> : null}
        <FormMessage />
      </FormItem>
    )} />
  );
}

function SelectField<T extends FieldValues>({ control, name, label: fieldLabel, options, optional = false, className }: { control: Control<T>; name: FieldPath<T>; label: string; options: { value: string; label: string; disabled?: boolean }[]; optional?: boolean; className?: string }) {
  return (
    <FormField control={control} name={name} render={({ field }) => (
      <FormItem className={className}>
        <FormLabel>{fieldLabel}</FormLabel>
        <Select value={String(field.value || (optional ? 'none' : ''))} onValueChange={(value) => field.onChange(value === 'none' ? '' : value)}>
          <FormControl><SelectTrigger className="h-11"><SelectValue placeholder={`Select ${fieldLabel.toLowerCase()}`} /></SelectTrigger></FormControl>
          <SelectContent><SelectGroup>
            {optional ? <SelectItem value="none">None</SelectItem> : null}
            {options.map((option) => <SelectItem key={option.value} value={option.value} disabled={option.disabled}>{option.label}</SelectItem>)}
          </SelectGroup></SelectContent>
        </Select>
        <FormMessage />
      </FormItem>
    )} />
  );
}

function SwitchField<T extends FieldValues>({ control, name, label: fieldLabel, description }: { control: Control<T>; name: FieldPath<T>; label: string; description?: string }) {
  return (
    <FormField control={control} name={name} render={({ field }) => (
      <FormItem className="flex min-h-20 flex-row items-center justify-between gap-4 rounded-lg border p-3">
        <div className="flex flex-col gap-1"><FormLabel>{fieldLabel}</FormLabel>{description ? <FormDescription>{description}</FormDescription> : null}</div>
        <FormControl><Switch checked={Boolean(field.value)} onCheckedChange={field.onChange} /></FormControl>
      </FormItem>
    )} />
  );
}

function errorMessage(error: unknown): string {
  if (error instanceof ApiError) return error.message;
  return error instanceof Error ? error.message : 'The record could not be saved.';
}
