import * as React from "react";
import { ChevronDownIcon, Plus, Trash2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { PROPERTY_ASSET_TYPES } from "@/lib/opportunity-constants";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Accordion,
  AccordionItem,
  AccordionContent,
} from "@/components/ui/accordion";
import { Checkbox } from "@/components/ui/checkbox";
import { DatePicker } from "@/components/ui/date-picker";
import { Slider } from "@/components/ui/slider";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import {
  AddressAutocomplete,
  CurrencyInputWithSlider,
  OwnershipSplit,
} from "@/components/ui/form-primitives";
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";

/**
 * Opportunity Edit Modals — WealthX DS (L4)
 *
 * Six focused edit dialogs for the Opportunity Details Drawer Summary tab:
 * - EditLoanScenarioModal   — edit loan quiz fields
 * - EditAssetsModal         — add/edit/remove asset line items
 * - EditDebtsModal          — add/edit/remove debt line items
 * - EditAboutApplicantModal — personal details (name, gender, phone, email…)
 * - EditIncomeModal         — income fields per applicant
 * - EditExpensesModal       — expense breakdown per applicant
 *
 * All modals are fully controlled. Each accepts initial data and fires
 * `onSave` with the updated payload when confirmed.
 */

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const LOAN_PURPOSES = [
  "Purchase a home",
  "Refinance my home loan",
  "Buy an investment property",
  "Refinance investment loan",
  "Renovate/build",
  "Equity release",
];

const ASSET_TYPES = [
  "Primary Residence",
  "Investment Property",
  "Holiday Home",
  "Commercial Property",
  "Rural Property",
  "Cash & Savings",
  "Term Deposit",
  "Shares / ETFs",
  "Managed Funds",
  "Superannuation",
  "Motor Vehicle",
  "Business Equity",
  "Cryptocurrency",
  "Personal Belongings",
  "Life Insurance",
  "Trust Assets",
  "SMSF",
  "Bonds / Fixed Income",
  "Other",
];

const PROPERTY_SUBTYPES = [
  "House",
  "Unit / Apartment",
  "Townhouse",
  "Land",
  "Rural / Farm",
  "Commercial",
];

const PROPERTY_USED_AS = ["Owner Occupied", "Investment", "Vacant Land"];

const FINANCIAL_ACCOUNT_ASSET_TYPES = new Set([
  "Cash & Savings",
  "Term Deposit",
]);

const INVESTMENT_ASSET_TYPES = new Set([
  "Shares / ETFs",
  "Managed Funds",
  "Bonds / Fixed Income",
  "Cryptocurrency",
]);

const SUPER_ASSET_TYPES = new Set(["Superannuation", "SMSF"]);

// Fields shown per asset type category
function assetFields(type: string) {
  return {
    isProperty: PROPERTY_ASSET_TYPES.has(type),
    isVehicle: type === "Motor Vehicle",
    isFinancialAccount: FINANCIAL_ACCOUNT_ASSET_TYPES.has(type),
    isInvestment: INVESTMENT_ASSET_TYPES.has(type),
    isSuper: SUPER_ASSET_TYPES.has(type),
    isBusiness: type === "Business Equity",
    isInsurance: type === "Life Insurance",
  };
}

const PROPERTY_LOAN_DEBT_TYPES = new Set([
  "Home Loan (Owner Occupied)",
  "Home Loan (Investment)",
  "Construction Loan",
]);

const GENERAL_LOAN_DEBT_TYPES = new Set([
  "Personal Loan",
  "Business Loan",
  "Overdraft",
  "Line of Credit",
  "Guarantor Liability",
]);

const CARD_DEBT_TYPES = new Set([
  "Credit Card",
  "Store Card",
  "Buy Now Pay Later",
]);

const VEHICLE_DEBT_TYPES = new Set(["Car Loan", "Vehicle Lease"]);

function debtFields(type: string) {
  return {
    isPropertyLoan: PROPERTY_LOAN_DEBT_TYPES.has(type),
    isGeneralLoan: GENERAL_LOAN_DEBT_TYPES.has(type),
    isCard: CARD_DEBT_TYPES.has(type),
    isVehicle: VEHICLE_DEBT_TYPES.has(type),
    isHecs: type === "HECS / Student Debt",
    isTax: type === "Tax Debt",
    isGuarantor: type === "Guarantor Liability",
  };
}

const DEBT_TYPES = [
  "Home Loan (Owner Occupied)",
  "Home Loan (Investment)",
  "Construction Loan",
  "Personal Loan",
  "Car Loan",
  "Credit Card",
  "Store Card",
  "HECS / Student Debt",
  "Business Loan",
  "Overdraft",
  "Tax Debt",
  "Buy Now Pay Later",
  "Vehicle Lease",
  "Guarantor Liability",
  "Line of Credit",
  "Other",
];

const TITLE_OPTIONS = ["Mr", "Mrs", "Ms", "Dr", "Prof"];

const GENDER_OPTIONS = ["Male", "Female", "Non-binary", "Prefer not to say"];

const MARITAL_OPTIONS = [
  "Single",
  "Married",
  "De facto",
  "Divorced",
  "Widowed",
];

const CITIZEN_OPTIONS = [
  "Australian Citizen",
  "Permanent Resident",
  "Temporary Resident",
  "Foreign National",
];

const RESIDENTIAL_STATUS_OPTIONS = [
  "Own",
  "Renting",
  "Boarding",
  "With Parents",
  "Other",
];

const PROPERTY_IN_TRUST_OPTIONS = ["None", "Yes - Discretionary", "Yes - Unit"];

const COMPANY_OWNERSHIP_OPTIONS = [
  "None",
  "Yes - Director",
  "Yes - Shareholder",
];

const INCOME_TYPES = [
  "PAYG",
  "Self-employed",
  "Contractor",
  "Casual",
  "Commission",
  "Government Benefits",
  "Rental",
  "Other",
];

const EXPENSE_TYPES = [
  "Groceries",
  "Dining Out",
  "Transport",
  "Fuel",
  "Utilities",
  "Phone Plan",
  "Internet",
  "Medical",
  "Entertainment",
  "Clothing",
  "Gym & Fitness",
  "Subscriptions",
  "Childcare",
  "Education",
  "Pet Care",
  "Insurance",
  "Council Rates",
  "Body Corp / Strata",
  "Home Maintenance",
  "Travel & Holidays",
  "Donations",
  "Other",
];

const PRIORITIES = [
  "Maximize Borrow Amount",
  "Cheapest Interest Rate",
  "The Best Features",
  "Major Lender",
  "Small Lender",
  "Regional Lender",
  "Non-Bank Lender",
  "Branch Network",
  "Good Customer Service",
  "Environmentally Friendly Lender",
];

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

// --- Loan Scenario ---
export interface LoanScenarioFormData {
  loanPurpose: string;
  propertyEstimate: number;
  cashEquity: number;
  loanAmount: number;
  loanDuration: number;
  knowsFeatures: string;
  featureFixedRate: boolean;
  featureVariableRate: boolean;
  featureSplitLoan: boolean;
  featureInterestOnly: boolean;
  featureRedrawFacility: boolean;
  feature100Offset: boolean;
  priorities: string[];
  borrowOtherThanProperty: string;
  concernedAboutRates: string;
  considerFixedRate: string;
  retirementAge: string;
  anticipatedChanges: string;
}

// --- Assets ---
export interface AssetLineItem {
  id: string;
  assetType: string;
  value: number;
  mainShare: number;
  coShare: number;

  // Property
  address?: string;
  propertySubtype?: string;
  usedAs?: string;

  // Vehicle
  make?: string;
  model?: string;
  year?: string;

  // Financial accounts (Cash, Term Deposit) + Investments + Crypto
  institution?: string;

  // Superannuation / SMSF
  fundName?: string;
  memberNumber?: string;

  // Business Equity
  businessName?: string;
  abn?: string;

  // Life Insurance
  insurer?: string;
  policyNumber?: string;
}

// --- Debts ---
export interface DebtLineItem {
  id: string;
  debtType: string;
  amountOwing: number;
  originalLoanAmount: number;
  repaymentAmount: number;
  repaymentFrequency: "Monthly" | "Weekly";
  interestRate: string;
  details: string;
  mainShare: number;
  coShare: number;

  // Property loans
  lender?: string;
  accountNumber?: string;
  propertyAddress?: string;

  // Vehicle loans/leases
  vehicleMake?: string;
  vehicleModel?: string;
  vehicleYear?: string;

  // Cards / BNPL
  creditLimit?: number;

  // HECS
  institution?: string;

  // Tax debt
  taxYear?: string;
  referenceNumber?: string;

  // Guarantor liability
  beneficiary?: string;
}

// --- About ---
export interface DependantInfo {
  dob: string;
}

export interface AboutApplicantFormData {
  // Name
  title: string;
  firstName: string;
  lastName: string;

  // Contact
  phone: string;
  email: string;

  // Personal
  dob: string;
  gender: string;
  maritalStatus: string;
  numDependants: string;
  dependants: DependantInfo[];

  // Residency & ID
  citizenStatus: string;
  residentialAddress: string;
  residentialStatus: string;
  timeAtAddressYears: string;
  timeAtAddressMonths: string;
  previousAddress: string;
  driversLicence: string;
  passport: string;

  // Financial structure
  propertyInTrust: string;
  companyOwnership: string;
}

// --- Income (array-based) ---
export interface IncomeItem {
  id: string;
  incomeType: string;
  jobTitle: string;
  startDate: string;
  stillInPosition: boolean;
  endDate: string;
  companyName: string;
  companyAddress: string;
  incomeAmount: number;
  frequency: "Monthly" | "Weekly";
  companyType: "Public" | "Private" | "";
}

export interface IncomeFormData {
  items: IncomeItem[];
}

// --- Expenses (array-based) ---
export interface ExpenseItem {
  id: string;
  expenseType: string;
  amount: number;
  frequency: "Monthly" | "Weekly";
  mainShare: number;
  coShare: number;
}

export interface ExpensesFormData {
  items: ExpenseItem[];
}

// ---------------------------------------------------------------------------
// Prop interfaces
// ---------------------------------------------------------------------------

export interface EditLoanScenarioModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  initialData?: Partial<LoanScenarioFormData>;
  onSave: (data: LoanScenarioFormData) => void;
  mainApplicantName?: string;
  coApplicantName?: string;
  /** Scope the dialog portal into this element (e.g. a Sheet drawer) instead of document.body. */
  container?: HTMLElement | null;
  className?: string;
}

export interface EditAssetsModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  initialItems?: AssetLineItem[];
  onSave: (items: AssetLineItem[]) => void;
  mainApplicantName?: string;
  coApplicantName?: string;
  container?: HTMLElement | null;
  className?: string;
}

export interface EditDebtsModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  initialItems?: DebtLineItem[];
  onSave: (items: DebtLineItem[]) => void;
  mainApplicantName?: string;
  coApplicantName?: string;
  container?: HTMLElement | null;
  className?: string;
}

export interface EditAboutApplicantModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  applicantLabel?: string;
  initialData?: Partial<AboutApplicantFormData>;
  onSave: (data: AboutApplicantFormData) => void;
  container?: HTMLElement | null;
  className?: string;
}

export interface EditIncomeModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  applicantLabel?: string;
  initialData?: IncomeFormData;
  onSave: (data: IncomeFormData) => void;
  container?: HTMLElement | null;
  className?: string;
}

export interface EditExpensesModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  applicantLabel?: string;
  initialData?: ExpensesFormData;
  onSave: (data: ExpensesFormData) => void;
  container?: HTMLElement | null;
  className?: string;
}

// ---------------------------------------------------------------------------
// Shared internal helpers
// ---------------------------------------------------------------------------

function FormField({
  label,
  children,
  className,
}: {
  label: string;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <div className={cn("flex flex-col gap-1.5", className)}>
      <Label className="text-sm font-medium text-muted-foreground">
        {label}
      </Label>
      {children}
    </div>
  );
}

function ModalScroll({ children }: { children: React.ReactNode }) {
  return (
    <div className="max-h-[65vh] overflow-y-auto flex flex-col gap-4 py-1 pr-1">
      {children}
    </div>
  );
}

function FrequencyToggle({
  value,
  onValueChange,
}: {
  value: "Monthly" | "Weekly";
  onValueChange: (val: "Monthly" | "Weekly") => void;
}) {
  return (
    <ToggleGroup
      variant="outline"
      value={[value]}
      onValueChange={(vals) => {
        const val = vals[0];
        if (val === "Monthly" || val === "Weekly") {
          onValueChange(val);
        }
      }}
    >
      <ToggleGroupItem value="Monthly" size="sm">
        Monthly
      </ToggleGroupItem>
      <ToggleGroupItem value="Weekly" size="sm">
        Weekly
      </ToggleGroupItem>
    </ToggleGroup>
  );
}

function AccordionItemHeader({
  label,
  onRemove,
  removeLabel = "Remove item",
}: {
  label: string;
  onRemove: () => void;
  removeLabel?: string;
}) {
  return (
    <AccordionPrimitive.Header className="flex items-center">
      <AccordionPrimitive.Trigger
        className={cn(
          "flex flex-1 items-center justify-between gap-4 py-4 text-left",
          "text-label-medium rounded-none outline-none transition-[color,opacity]",
          "hover:underline focus-visible:ring-2 focus-visible:ring-foreground/30",
          "[&[data-panel-open]>svg]:rotate-180",
        )}
      >
        {label}
        <ChevronDownIcon className="pointer-events-none size-4 shrink-0 text-muted-foreground transition-transform duration-200" />
      </AccordionPrimitive.Trigger>
      <Button
        type="button"
        variant="ghost"
        size="icon"
        onClick={onRemove}
        className="size-8 shrink-0"
        aria-label={removeLabel}
      >
        <Trash2 className="size-3.5 text-destructive" />
      </Button>
    </AccordionPrimitive.Header>
  );
}

// ---------------------------------------------------------------------------
// Defaults
// ---------------------------------------------------------------------------

const LOAN_SCENARIO_DEFAULTS: LoanScenarioFormData = {
  loanPurpose: "",
  propertyEstimate: 0,
  cashEquity: 0,
  loanAmount: 0,
  loanDuration: 30,
  knowsFeatures: "",
  featureFixedRate: false,
  featureVariableRate: false,
  featureSplitLoan: false,
  featureInterestOnly: false,
  featureRedrawFacility: false,
  feature100Offset: false,
  priorities: [],
  borrowOtherThanProperty: "",
  concernedAboutRates: "",
  considerFixedRate: "",
  retirementAge: "",
  anticipatedChanges: "",
};

const ABOUT_APPLICANT_DEFAULTS: AboutApplicantFormData = {
  title: "",
  firstName: "",
  lastName: "",
  phone: "",
  email: "",
  dob: "",
  gender: "",
  maritalStatus: "",
  numDependants: "",
  dependants: [],
  citizenStatus: "",
  residentialAddress: "",
  residentialStatus: "",
  timeAtAddressYears: "",
  timeAtAddressMonths: "",
  previousAddress: "",
  driversLicence: "",
  passport: "",
  propertyInTrust: "",
  companyOwnership: "",
};

function makeDefaultIncomeItem(): IncomeItem {
  return {
    id: `income-${Date.now()}-${Math.random()}`,
    incomeType: "",
    jobTitle: "",
    startDate: "",
    stillInPosition: true,
    endDate: "",
    companyName: "",
    companyAddress: "",
    incomeAmount: 0,
    frequency: "Monthly",
    companyType: "",
  };
}

function makeDefaultAssetItem(): AssetLineItem {
  return {
    id: `asset-${Date.now()}-${Math.random()}`,
    assetType: "",
    value: 0,
    mainShare: 100,
    coShare: 0,
  };
}

function makeDefaultDebtItem(): DebtLineItem {
  return {
    id: `debt-${Date.now()}-${Math.random()}`,
    debtType: "",
    amountOwing: 0,
    originalLoanAmount: 0,
    repaymentAmount: 0,
    repaymentFrequency: "Monthly",
    interestRate: "",
    details: "",
    mainShare: 100,
    coShare: 0,
  };
}

function makeDefaultExpenseItem(): ExpenseItem {
  return {
    id: `expense-${Date.now()}-${Math.random()}`,
    expenseType: "",
    amount: 0,
    frequency: "Monthly",
    mainShare: 100,
    coShare: 0,
  };
}

// ---------------------------------------------------------------------------
// EditLoanScenarioModal
// ---------------------------------------------------------------------------

export function EditLoanScenarioModal({
  open,
  onOpenChange,
  initialData,
  onSave,
  container,
  className,
}: EditLoanScenarioModalProps) {
  const [form, setForm] = React.useState<LoanScenarioFormData>({
    ...LOAN_SCENARIO_DEFAULTS,
    ...initialData,
  });

  const initialSnapshot = React.useRef<string>("");

  React.useEffect(() => {
    if (open) {
      const data = { ...LOAN_SCENARIO_DEFAULTS, ...initialData };
      setForm(data);
      initialSnapshot.current = JSON.stringify(data);
    }
  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps

  const isDirty = JSON.stringify(form) !== initialSnapshot.current;

  const set = <K extends keyof LoanScenarioFormData>(
    key: K,
    val: LoanScenarioFormData[K],
  ) => setForm((prev) => ({ ...prev, [key]: val }));

  const togglePriority = (priority: string) => {
    setForm((prev) => {
      const exists = prev.priorities.includes(priority);
      if (exists) {
        return {
          ...prev,
          priorities: prev.priorities.filter((p) => p !== priority),
        };
      }
      if (prev.priorities.length >= 3) return prev;
      return { ...prev, priorities: [...prev.priorities, priority] };
    });
  };

  const prioritiesAtMax = form.priorities.length >= 3;

  const LOAN_FEATURES: { key: keyof LoanScenarioFormData; label: string }[] = [
    { key: "featureFixedRate", label: "Fixed Rate" },
    { key: "featureVariableRate", label: "Variable Rate" },
    { key: "featureSplitLoan", label: "Split Loan" },
    { key: "featureInterestOnly", label: "Interest Only" },
    { key: "featureRedrawFacility", label: "Redraw Facility" },
    { key: "feature100Offset", label: "100% Offset" },
  ];

  const YES_NO_FIELDS: { key: keyof LoanScenarioFormData; label: string }[] = [
    {
      key: "borrowOtherThanProperty",
      label: "Do you intend to borrow money other than your property?",
    },
    {
      key: "concernedAboutRates",
      label: "Are you concerned about rising interest rates?",
    },
    {
      key: "considerFixedRate",
      label: "Would you consider taking a fixed rate?",
    },
    {
      key: "anticipatedChanges",
      label: "Anticipated changes impacting repayment?",
    },
  ];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent
        className={cn("max-w-lg", className)}
        container={container}
      >
        <DialogHeader>
          <DialogTitle>Edit Loan Scenario</DialogTitle>
        </DialogHeader>
        <ModalScroll>
          {/* 1. Loan purpose */}
          <FormField label="What would you like to do?">
            <Select
              value={form.loanPurpose}
              onValueChange={(val) => set("loanPurpose", val ?? "")}
            >
              <SelectTrigger className="w-full">
                <SelectValue placeholder="Select purpose" />
              </SelectTrigger>
              <SelectContent>
                {LOAN_PURPOSES.map((p) => (
                  <SelectItem key={p} value={p}>
                    {p}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </FormField>

          {/* 2. Two-column: property estimate | cash equity */}
          <div className="grid grid-cols-2 gap-4">
            <FormField label="Property Estimate">
              <CurrencyInputWithSlider
                value={form.propertyEstimate}
                min={0}
                max={10_000_000}
                step={50_000}
                onValueChange={(val) => set("propertyEstimate", val)}
              />
            </FormField>
            <FormField label="Cash/equity towards property">
              <CurrencyInputWithSlider
                value={form.cashEquity}
                min={0}
                max={2_000_000}
                step={5_000}
                onValueChange={(val) => set("cashEquity", val)}
              />
            </FormField>
          </div>

          {/* 3. Two-column: loan amount | loan duration */}
          <div className="grid grid-cols-2 gap-4">
            <FormField label="Loan Amount">
              <CurrencyInputWithSlider
                value={form.loanAmount}
                min={0}
                max={5_000_000}
                step={10_000}
                onValueChange={(val) => set("loanAmount", val)}
              />
            </FormField>
            <FormField label="Loan Duration">
              <div className="flex flex-col gap-2">
                <div className="flex items-center gap-2">
                  <Input
                    type="number"
                    min={1}
                    max={40}
                    value={form.loanDuration}
                    onChange={(e) => {
                      const parsed = parseInt(e.target.value, 10);
                      if (!isNaN(parsed)) {
                        set("loanDuration", Math.min(40, Math.max(1, parsed)));
                      }
                    }}
                    className="flex-1"
                  />
                  <span className="text-sm text-muted-foreground">years</span>
                </div>
                <Slider
                  min={1}
                  max={40}
                  step={1}
                  value={form.loanDuration}
                  onValueChange={(val) => set("loanDuration", val)}
                />
              </div>
            </FormField>
          </div>

          {/* 4. Do you know what loan features you want? */}
          <FormField label="Do you know what loan features you want?">
            <Select
              value={form.knowsFeatures}
              onValueChange={(val) => set("knowsFeatures", val ?? "")}
            >
              <SelectTrigger className="w-full">
                <SelectValue placeholder="Select" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="Yes">Yes</SelectItem>
                <SelectItem value="No">No</SelectItem>
              </SelectContent>
            </Select>
          </FormField>

          {/* 5. Features grid — only when knowsFeatures == "Yes" */}
          {form.knowsFeatures === "Yes" && (
            <div className="flex flex-col gap-2">
              <Label className="text-sm font-medium text-muted-foreground">
                What features are important to you?
              </Label>
              <div className="grid grid-cols-2 gap-2">
                {LOAN_FEATURES.map(({ key, label }) => (
                  <div key={key} className="flex items-center gap-2">
                    <Checkbox
                      id={`feature-${key}`}
                      checked={form[key] as boolean}
                      onCheckedChange={(checked) => set(key, checked === true)}
                    />
                    <label
                      htmlFor={`feature-${key}`}
                      className="text-sm cursor-pointer select-none"
                    >
                      {label}
                    </label>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* 6. Top 3 priorities */}
          <div className="flex flex-col gap-2">
            <Label className="text-sm font-medium text-muted-foreground">
              Top 3 Priorities (Select up to 3)
            </Label>
            <div className="grid grid-cols-2 gap-2">
              {PRIORITIES.map((priority) => {
                const checked = form.priorities.includes(priority);
                const disabled = prioritiesAtMax && !checked;
                return (
                  <div key={priority} className="flex items-center gap-2">
                    <Checkbox
                      id={`priority-${priority}`}
                      checked={checked}
                      disabled={disabled}
                      onCheckedChange={() => togglePriority(priority)}
                    />
                    <label
                      htmlFor={`priority-${priority}`}
                      className={cn(
                        "text-sm cursor-pointer select-none",
                        disabled && "opacity-40 cursor-not-allowed",
                      )}
                    >
                      {priority}
                    </label>
                  </div>
                );
              })}
            </div>
          </div>

          {/* 7. Yes/No radio sections */}
          {YES_NO_FIELDS.map(({ key, label }) => (
            <div key={key} className="flex flex-col gap-2">
              <Label className="text-sm font-medium text-muted-foreground">
                {label}
              </Label>
              <RadioGroup
                value={form[key] as string}
                onValueChange={(val) => {
                  if (val === "Yes" || val === "No") set(key, val);
                }}
                className="flex gap-4"
              >
                {(["Yes", "No"] as const).map((opt) => (
                  <label
                    key={opt}
                    className="flex items-center gap-2 cursor-pointer select-none"
                  >
                    <RadioGroupItem value={opt} />
                    <span className="text-sm">{opt}</span>
                  </label>
                ))}
              </RadioGroup>
            </div>
          ))}

          {/* 8. Retirement age */}
          <FormField label="What age are you planning to retire?">
            <Input
              type="number"
              min={0}
              max={100}
              value={form.retirementAge}
              onChange={(e) => set("retirementAge", e.target.value)}
              placeholder="e.g. 65"
            />
          </FormField>
        </ModalScroll>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!isDirty}
            onClick={() => {
              onSave(form);
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// EditAssetsModal
// ---------------------------------------------------------------------------

export function EditAssetsModal({
  open,
  onOpenChange,
  initialItems = [],
  onSave,
  mainApplicantName = "Main Applicant",
  coApplicantName = "Co-Applicant",
  container,
  className,
}: EditAssetsModalProps) {
  const [items, setItems] = React.useState<AssetLineItem[]>(
    initialItems.length > 0 ? initialItems : [makeDefaultAssetItem()],
  );

  const initialSnapshot = React.useRef<string>("");

  React.useEffect(() => {
    if (open) {
      const data =
        initialItems.length > 0 ? initialItems : [makeDefaultAssetItem()];
      setItems(data);
      initialSnapshot.current = JSON.stringify(data);
    }
  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps

  const isDirty = JSON.stringify(items) !== initialSnapshot.current;

  const updateItem = <K extends keyof AssetLineItem>(
    id: string,
    key: K,
    val: AssetLineItem[K],
  ) =>
    setItems((prev) =>
      prev.map((item) => (item.id === id ? { ...item, [key]: val } : item)),
    );

  const removeItem = (id: string) =>
    setItems((prev) => prev.filter((item) => item.id !== id));

  const addItem = () => setItems((prev) => [...prev, makeDefaultAssetItem()]);

  const defaultOpenItems = items.length > 0 ? [items[0].id] : [];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent
        className={cn("max-w-lg", className)}
        container={container}
      >
        <DialogHeader>
          <DialogTitle>Edit Assets</DialogTitle>
        </DialogHeader>
        <ModalScroll>
          <Accordion
            multiple
            defaultValue={defaultOpenItems}
            className="w-full"
          >
            {items.map((item, index) => (
              <AccordionItem key={item.id} value={item.id}>
                {/* Custom header: trigger + delete button as siblings */}
                <AccordionItemHeader
                  label={`Asset ${index + 1} — ${item.assetType || "New Asset"}`}
                  onRemove={() => removeItem(item.id)}
                  removeLabel="Remove asset"
                />
                <AccordionContent>
                  <div className="flex flex-col gap-4 pt-1">
                    <FormField label="Asset Type">
                      <Select
                        value={item.assetType}
                        onValueChange={(val) =>
                          updateItem(item.id, "assetType", val ?? "")
                        }
                      >
                        <SelectTrigger className="w-full">
                          <SelectValue placeholder="Select type" />
                        </SelectTrigger>
                        <SelectContent>
                          {ASSET_TYPES.map((t) => (
                            <SelectItem key={t} value={t}>
                              {t}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </FormField>

                    <FormField label="Value">
                      <CurrencyInputWithSlider
                        value={item.value}
                        min={0}
                        max={10_000_000}
                        step={10_000}
                        onValueChange={(val) =>
                          updateItem(item.id, "value", val)
                        }
                      />
                    </FormField>

                    {/* Conditional fields based on asset type */}
                    {(() => {
                      const f = assetFields(item.assetType);
                      return (
                        <>
                          {f.isProperty && (
                            <>
                              <FormField label="Property Address">
                                <AddressAutocomplete
                                  value={item.address ?? ""}
                                  onValueChange={(val) =>
                                    updateItem(item.id, "address", val)
                                  }
                                  onSelect={(opt) =>
                                    updateItem(item.id, "address", opt.label)
                                  }
                                />
                              </FormField>
                              <div className="grid grid-cols-2 gap-4">
                                <FormField label="Property Type">
                                  <Select
                                    value={item.propertySubtype ?? ""}
                                    onValueChange={(val) =>
                                      updateItem(
                                        item.id,
                                        "propertySubtype",
                                        val ?? "",
                                      )
                                    }
                                  >
                                    <SelectTrigger className="w-full">
                                      <SelectValue placeholder="Select" />
                                    </SelectTrigger>
                                    <SelectContent>
                                      {PROPERTY_SUBTYPES.map((t) => (
                                        <SelectItem key={t} value={t}>
                                          {t}
                                        </SelectItem>
                                      ))}
                                    </SelectContent>
                                  </Select>
                                </FormField>
                                <FormField label="Used As">
                                  <Select
                                    value={item.usedAs ?? ""}
                                    onValueChange={(val) =>
                                      updateItem(item.id, "usedAs", val ?? "")
                                    }
                                  >
                                    <SelectTrigger className="w-full">
                                      <SelectValue placeholder="Select" />
                                    </SelectTrigger>
                                    <SelectContent>
                                      {PROPERTY_USED_AS.map((t) => (
                                        <SelectItem key={t} value={t}>
                                          {t}
                                        </SelectItem>
                                      ))}
                                    </SelectContent>
                                  </Select>
                                </FormField>
                              </div>
                            </>
                          )}

                          {f.isVehicle && (
                            <div className="grid grid-cols-3 gap-4">
                              <FormField label="Make">
                                <Input
                                  value={item.make ?? ""}
                                  onChange={(e) =>
                                    updateItem(item.id, "make", e.target.value)
                                  }
                                  placeholder="e.g. Toyota"
                                />
                              </FormField>
                              <FormField label="Model">
                                <Input
                                  value={item.model ?? ""}
                                  onChange={(e) =>
                                    updateItem(item.id, "model", e.target.value)
                                  }
                                  placeholder="e.g. Camry"
                                />
                              </FormField>
                              <FormField label="Year">
                                <Input
                                  type="number"
                                  min={1900}
                                  max={new Date().getFullYear() + 1}
                                  value={item.year ?? ""}
                                  onChange={(e) =>
                                    updateItem(item.id, "year", e.target.value)
                                  }
                                  placeholder="e.g. 2022"
                                />
                              </FormField>
                            </div>
                          )}

                          {(f.isFinancialAccount || f.isInvestment) && (
                            <FormField label="Institution / Platform">
                              <Input
                                value={item.institution ?? ""}
                                onChange={(e) =>
                                  updateItem(
                                    item.id,
                                    "institution",
                                    e.target.value,
                                  )
                                }
                                placeholder="e.g. CommBank, Vanguard"
                              />
                            </FormField>
                          )}

                          {f.isSuper && (
                            <div className="grid grid-cols-2 gap-4">
                              <FormField label="Fund Name">
                                <Input
                                  value={item.fundName ?? ""}
                                  onChange={(e) =>
                                    updateItem(
                                      item.id,
                                      "fundName",
                                      e.target.value,
                                    )
                                  }
                                  placeholder="e.g. Australian Super"
                                />
                              </FormField>
                              <FormField label="Member Number">
                                <Input
                                  value={item.memberNumber ?? ""}
                                  onChange={(e) =>
                                    updateItem(
                                      item.id,
                                      "memberNumber",
                                      e.target.value,
                                    )
                                  }
                                  placeholder="e.g. 1234567"
                                />
                              </FormField>
                            </div>
                          )}

                          {f.isBusiness && (
                            <div className="grid grid-cols-2 gap-4">
                              <FormField label="Business Name">
                                <Input
                                  value={item.businessName ?? ""}
                                  onChange={(e) =>
                                    updateItem(
                                      item.id,
                                      "businessName",
                                      e.target.value,
                                    )
                                  }
                                  placeholder="e.g. Acme Pty Ltd"
                                />
                              </FormField>
                              <FormField label="ABN">
                                <Input
                                  value={item.abn ?? ""}
                                  onChange={(e) =>
                                    updateItem(item.id, "abn", e.target.value)
                                  }
                                  placeholder="e.g. 12 345 678 901"
                                />
                              </FormField>
                            </div>
                          )}

                          {f.isInsurance && (
                            <div className="grid grid-cols-2 gap-4">
                              <FormField label="Insurer">
                                <Input
                                  value={item.insurer ?? ""}
                                  onChange={(e) =>
                                    updateItem(
                                      item.id,
                                      "insurer",
                                      e.target.value,
                                    )
                                  }
                                  placeholder="e.g. TAL, AIA"
                                />
                              </FormField>
                              <FormField label="Policy Number">
                                <Input
                                  value={item.policyNumber ?? ""}
                                  onChange={(e) =>
                                    updateItem(
                                      item.id,
                                      "policyNumber",
                                      e.target.value,
                                    )
                                  }
                                  placeholder="e.g. POL-123456"
                                />
                              </FormField>
                            </div>
                          )}
                        </>
                      );
                    })()}

                    <FormField label="Ownership (%)">
                      <OwnershipSplit
                        owners={[
                          {
                            id: "main",
                            name: mainApplicantName ?? "Main Applicant",
                            share: item.mainShare,
                          },
                          {
                            id: "co",
                            name: coApplicantName ?? "Co-Applicant",
                            share: item.coShare,
                          },
                        ]}
                        onOwnersChange={(owners) => {
                          updateItem(
                            item.id,
                            "mainShare",
                            owners.find((o) => o.id === "main")?.share ?? 50,
                          );
                          updateItem(
                            item.id,
                            "coShare",
                            owners.find((o) => o.id === "co")?.share ?? 50,
                          );
                        }}
                      />
                    </FormField>
                  </div>
                </AccordionContent>
              </AccordionItem>
            ))}
          </Accordion>

          <Button
            variant="outline"
            onClick={addItem}
            className="w-full gap-1.5"
          >
            <Plus className="h-4 w-4" />
            Add More
          </Button>
        </ModalScroll>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!isDirty}
            onClick={() => {
              onSave(items);
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// EditDebtsModal
// ---------------------------------------------------------------------------

export function EditDebtsModal({
  open,
  onOpenChange,
  initialItems = [],
  onSave,
  mainApplicantName = "Main Applicant",
  coApplicantName = "Co-Applicant",
  container,
  className,
}: EditDebtsModalProps) {
  const [items, setItems] = React.useState<DebtLineItem[]>(
    initialItems.length > 0 ? initialItems : [makeDefaultDebtItem()],
  );

  const initialSnapshot = React.useRef<string>("");

  React.useEffect(() => {
    if (open) {
      const data =
        initialItems.length > 0 ? initialItems : [makeDefaultDebtItem()];
      setItems(data);
      initialSnapshot.current = JSON.stringify(data);
    }
  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps

  const isDirty = JSON.stringify(items) !== initialSnapshot.current;

  const updateItem = <K extends keyof DebtLineItem>(
    id: string,
    key: K,
    val: DebtLineItem[K],
  ) =>
    setItems((prev) =>
      prev.map((item) => (item.id === id ? { ...item, [key]: val } : item)),
    );

  const removeItem = (id: string) =>
    setItems((prev) => prev.filter((item) => item.id !== id));

  const addItem = () => setItems((prev) => [...prev, makeDefaultDebtItem()]);

  const defaultOpenItems = items.length > 0 ? [items[0].id] : [];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent
        className={cn("max-w-xl", className)}
        container={container}
      >
        <DialogHeader>
          <DialogTitle>Edit Debts</DialogTitle>
        </DialogHeader>
        <ModalScroll>
          <Accordion
            multiple
            defaultValue={defaultOpenItems}
            className="w-full"
          >
            {items.map((item) => {
              const df = debtFields(item.debtType);
              return (
                <AccordionItem key={item.id} value={item.id}>
                  <AccordionItemHeader
                    label={item.debtType || "New Debt"}
                    onRemove={() => removeItem(item.id)}
                    removeLabel="Remove debt"
                  />
                  <AccordionContent>
                    <div className="flex flex-col gap-4 pt-1">
                      <FormField label="Debt Type">
                        <Select
                          value={item.debtType}
                          onValueChange={(val) =>
                            updateItem(item.id, "debtType", val ?? "")
                          }
                        >
                          <SelectTrigger className="w-full">
                            <SelectValue placeholder="Select type" />
                          </SelectTrigger>
                          <SelectContent>
                            {DEBT_TYPES.map((t) => (
                              <SelectItem key={t} value={t}>
                                {t}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </FormField>

                      {/* Conditional fields by debt type */}
                      {(df.isPropertyLoan ||
                        df.isGeneralLoan ||
                        df.isVehicle) && (
                        <div className="grid grid-cols-2 gap-4">
                          <FormField label="Lender">
                            <Input
                              value={item.lender ?? ""}
                              onChange={(e) =>
                                updateItem(item.id, "lender", e.target.value)
                              }
                              placeholder="e.g. CommBank"
                            />
                          </FormField>
                          <FormField label="Account Number">
                            <Input
                              value={item.accountNumber ?? ""}
                              onChange={(e) =>
                                updateItem(
                                  item.id,
                                  "accountNumber",
                                  e.target.value,
                                )
                              }
                              placeholder="e.g. 123-456"
                            />
                          </FormField>
                        </div>
                      )}

                      {df.isPropertyLoan && (
                        <FormField label="Property Address">
                          <AddressAutocomplete
                            value={item.propertyAddress ?? ""}
                            onValueChange={(val) =>
                              updateItem(item.id, "propertyAddress", val)
                            }
                            onSelect={(opt) =>
                              updateItem(item.id, "propertyAddress", opt.label)
                            }
                          />
                        </FormField>
                      )}

                      {df.isVehicle && (
                        <div className="grid grid-cols-3 gap-4">
                          <FormField label="Make">
                            <Input
                              value={item.vehicleMake ?? ""}
                              onChange={(e) =>
                                updateItem(
                                  item.id,
                                  "vehicleMake",
                                  e.target.value,
                                )
                              }
                              placeholder="e.g. Toyota"
                            />
                          </FormField>
                          <FormField label="Model">
                            <Input
                              value={item.vehicleModel ?? ""}
                              onChange={(e) =>
                                updateItem(
                                  item.id,
                                  "vehicleModel",
                                  e.target.value,
                                )
                              }
                              placeholder="e.g. Camry"
                            />
                          </FormField>
                          <FormField label="Year">
                            <Input
                              type="number"
                              min={1900}
                              max={new Date().getFullYear() + 1}
                              value={item.vehicleYear ?? ""}
                              onChange={(e) =>
                                updateItem(
                                  item.id,
                                  "vehicleYear",
                                  e.target.value,
                                )
                              }
                              placeholder="e.g. 2022"
                            />
                          </FormField>
                        </div>
                      )}

                      {df.isCard && (
                        <div className="grid grid-cols-2 gap-4">
                          <FormField label="Provider">
                            <Input
                              value={item.lender ?? ""}
                              onChange={(e) =>
                                updateItem(item.id, "lender", e.target.value)
                              }
                              placeholder="e.g. ANZ, Afterpay"
                            />
                          </FormField>
                          <FormField label="Credit Limit">
                            <CurrencyInputWithSlider
                              value={item.creditLimit ?? 0}
                              min={0}
                              max={100_000}
                              step={500}
                              onValueChange={(val) =>
                                updateItem(item.id, "creditLimit", val)
                              }
                            />
                          </FormField>
                        </div>
                      )}

                      {df.isHecs && (
                        <FormField label="Institution">
                          <Input
                            value={item.institution ?? ""}
                            onChange={(e) =>
                              updateItem(item.id, "institution", e.target.value)
                            }
                            placeholder="e.g. University of Sydney"
                          />
                        </FormField>
                      )}

                      {df.isTax && (
                        <div className="grid grid-cols-2 gap-4">
                          <FormField label="Tax Year">
                            <Input
                              value={item.taxYear ?? ""}
                              onChange={(e) =>
                                updateItem(item.id, "taxYear", e.target.value)
                              }
                              placeholder="e.g. 2023–24"
                            />
                          </FormField>
                          <FormField label="ATO Reference">
                            <Input
                              value={item.referenceNumber ?? ""}
                              onChange={(e) =>
                                updateItem(
                                  item.id,
                                  "referenceNumber",
                                  e.target.value,
                                )
                              }
                              placeholder="e.g. 1234567890"
                            />
                          </FormField>
                        </div>
                      )}

                      {df.isGuarantor && (
                        <FormField label="Beneficiary (borrower's name)">
                          <Input
                            value={item.beneficiary ?? ""}
                            onChange={(e) =>
                              updateItem(item.id, "beneficiary", e.target.value)
                            }
                            placeholder="e.g. Jane Smith"
                          />
                        </FormField>
                      )}

                      <div className="grid grid-cols-2 gap-4">
                        <FormField label="Amount Owing">
                          <CurrencyInputWithSlider
                            value={item.amountOwing}
                            min={0}
                            max={1_000_000}
                            step={1_000}
                            onValueChange={(val) =>
                              updateItem(item.id, "amountOwing", val)
                            }
                          />
                        </FormField>
                        <FormField label="Original Loan Amount">
                          <CurrencyInputWithSlider
                            value={item.originalLoanAmount}
                            min={0}
                            max={1_000_000}
                            step={1_000}
                            onValueChange={(val) =>
                              updateItem(item.id, "originalLoanAmount", val)
                            }
                          />
                        </FormField>
                      </div>

                      <div className="flex items-start gap-3">
                        <div className="flex-1">
                          <FormField label="Repayments">
                            <CurrencyInputWithSlider
                              value={item.repaymentAmount}
                              min={0}
                              max={1_000_000}
                              step={100}
                              onValueChange={(val) =>
                                updateItem(item.id, "repaymentAmount", val)
                              }
                            />
                          </FormField>
                        </div>
                        <div className="shrink-0 mt-[1.625rem]">
                          <FrequencyToggle
                            value={item.repaymentFrequency}
                            onValueChange={(val) =>
                              updateItem(item.id, "repaymentFrequency", val)
                            }
                          />
                        </div>
                      </div>

                      <FormField label="Interest Rate">
                        <div className="flex items-center gap-2">
                          <Input
                            value={item.interestRate}
                            onChange={(e) =>
                              updateItem(
                                item.id,
                                "interestRate",
                                e.target.value,
                              )
                            }
                            placeholder="e.g. 6.5"
                            className="flex-1"
                          />
                          <span className="text-sm text-muted-foreground shrink-0">
                            %
                          </span>
                        </div>
                      </FormField>

                      <FormField label="Notes">
                        <Textarea
                          value={item.details}
                          onChange={(e) =>
                            updateItem(item.id, "details", e.target.value)
                          }
                          placeholder="Short comment"
                          rows={2}
                        />
                      </FormField>

                      <FormField label="Ownership (%)">
                        <OwnershipSplit
                          owners={[
                            {
                              id: "main",
                              name: mainApplicantName ?? "Main Applicant",
                              share: item.mainShare,
                            },
                            {
                              id: "co",
                              name: coApplicantName ?? "Co-Applicant",
                              share: item.coShare,
                            },
                          ]}
                          onOwnersChange={(owners) => {
                            updateItem(
                              item.id,
                              "mainShare",
                              owners.find((o) => o.id === "main")?.share ?? 50,
                            );
                            updateItem(
                              item.id,
                              "coShare",
                              owners.find((o) => o.id === "co")?.share ?? 50,
                            );
                          }}
                        />
                      </FormField>
                    </div>
                  </AccordionContent>
                </AccordionItem>
              );
            })}
          </Accordion>

          <Button
            variant="outline"
            onClick={addItem}
            className="w-full gap-1.5"
          >
            <Plus className="h-4 w-4" />
            Add More
          </Button>
        </ModalScroll>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!isDirty}
            onClick={() => {
              onSave(items);
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// EditAboutApplicantModal
// ---------------------------------------------------------------------------

export function EditAboutApplicantModal({
  open,
  onOpenChange,
  applicantLabel = "Applicant",
  initialData,
  onSave,
  container,
  className,
}: EditAboutApplicantModalProps) {
  const [form, setForm] = React.useState<AboutApplicantFormData>({
    ...ABOUT_APPLICANT_DEFAULTS,
    ...initialData,
  });

  const initialSnapshot = React.useRef<string>("");

  React.useEffect(() => {
    if (open) {
      const data = { ...ABOUT_APPLICANT_DEFAULTS, ...initialData };
      setForm(data);
      initialSnapshot.current = JSON.stringify(data);
    }
  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps

  const isDirty = JSON.stringify(form) !== initialSnapshot.current;

  const setStr = (key: keyof AboutApplicantFormData) => (val: string | null) =>
    setForm((prev) => ({ ...prev, [key]: val ?? "" }));

  const handleNumDependantsChange = (val: string) => {
    const n = Math.max(0, Math.min(20, parseInt(val, 10) || 0));
    setForm((prev) => {
      const current = prev.dependants ?? [];
      const next: DependantInfo[] =
        n > current.length
          ? [...current, ...Array(n - current.length).fill({ dob: "" })]
          : current.slice(0, n);
      return { ...prev, numDependants: val, dependants: next };
    });
  };

  const setDependantDob = (index: number, dob: string) =>
    setForm((prev) => {
      const next = prev.dependants.map((d, i) => (i === index ? { dob } : d));
      return { ...prev, dependants: next };
    });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent
        className={cn("max-w-md", className)}
        container={container}
      >
        <DialogHeader>
          <DialogTitle>Edit About {applicantLabel}</DialogTitle>
        </DialogHeader>
        <ModalScroll>
          {/* Name */}
          <div className="flex gap-3 items-start">
            <div className="w-24 shrink-0">
              <FormField label="Title">
                <Select value={form.title} onValueChange={setStr("title")}>
                  <SelectTrigger className="w-full">
                    <SelectValue placeholder="Title" />
                  </SelectTrigger>
                  <SelectContent>
                    {TITLE_OPTIONS.map((t) => (
                      <SelectItem key={t} value={t}>
                        {t}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </FormField>
            </div>
            <FormField label="First Name" className="flex-1">
              <Input
                value={form.firstName}
                onChange={(e) => setStr("firstName")(e.target.value)}
                placeholder="First name"
              />
            </FormField>
            <FormField label="Last Name" className="flex-1">
              <Input
                value={form.lastName}
                onChange={(e) => setStr("lastName")(e.target.value)}
                placeholder="Last name"
              />
            </FormField>
          </div>

          {/* Contact */}
          <div className="grid grid-cols-2 gap-4">
            <FormField label="Phone Number">
              <Input
                value={form.phone}
                onChange={(e) => setStr("phone")(e.target.value)}
                placeholder="+61 4xx xxx xxx"
                type="tel"
              />
            </FormField>
            <FormField label="Email">
              <Input
                value={form.email}
                onChange={(e) => setStr("email")(e.target.value)}
                placeholder="email@example.com"
                type="email"
              />
            </FormField>
          </div>

          {/* Personal details */}
          <div className="grid grid-cols-2 gap-4">
            <FormField label="Date of Birth">
              <DatePicker
                value={form.dob ? new Date(form.dob) : undefined}
                onChange={(d) =>
                  setStr("dob")(d ? d.toISOString().slice(0, 10) : "")
                }
                calendarProps={{
                  fromYear: 1900,
                  toYear: new Date().getFullYear() - 16,
                }}
              />
            </FormField>
            <FormField label="Gender">
              <Select value={form.gender} onValueChange={setStr("gender")}>
                <SelectTrigger className="w-full">
                  <SelectValue placeholder="Select" />
                </SelectTrigger>
                <SelectContent>
                  {GENDER_OPTIONS.map((g) => (
                    <SelectItem key={g} value={g}>
                      {g}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <FormField label="Marital Status">
              <Select
                value={form.maritalStatus}
                onValueChange={setStr("maritalStatus")}
              >
                <SelectTrigger className="w-full">
                  <SelectValue placeholder="Select" />
                </SelectTrigger>
                <SelectContent>
                  {MARITAL_OPTIONS.map((m) => (
                    <SelectItem key={m} value={m}>
                      {m}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>
            <FormField label="No. of Dependants">
              <Input
                type="number"
                min={0}
                max={20}
                value={form.numDependants}
                onChange={(e) => handleNumDependantsChange(e.target.value)}
                placeholder="0"
              />
            </FormField>
          </div>

          {/* Dependant DOBs */}
          {form.dependants.length > 0 && (
            <div className="flex flex-col gap-3">
              <Label className="text-sm font-medium">
                Dependant Date of Birth
              </Label>
              <div className="grid grid-cols-2 gap-3">
                {form.dependants.map((dep, i) => (
                  <FormField key={i} label={`Dependant ${i + 1}`}>
                    <DatePicker
                      value={dep.dob ? new Date(dep.dob) : undefined}
                      onChange={(d) =>
                        setDependantDob(
                          i,
                          d ? d.toISOString().slice(0, 10) : "",
                        )
                      }
                      calendarProps={{
                        fromYear: 1900,
                        toYear: new Date().getFullYear(),
                      }}
                    />
                  </FormField>
                ))}
              </div>
            </div>
          )}

          {/* Residency */}
          <FormField label="Citizen Status">
            <Select
              value={form.citizenStatus}
              onValueChange={setStr("citizenStatus")}
            >
              <SelectTrigger className="w-full">
                <SelectValue placeholder="Select status" />
              </SelectTrigger>
              <SelectContent>
                {CITIZEN_OPTIONS.map((c) => (
                  <SelectItem key={c} value={c}>
                    {c}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </FormField>

          <FormField label="Current Residential Address">
            <AddressAutocomplete
              value={form.residentialAddress}
              onValueChange={setStr("residentialAddress")}
              onSelect={(opt) => setStr("residentialAddress")(opt.label)}
            />
          </FormField>

          <div className="grid grid-cols-2 gap-4">
            <FormField label="Residential Status">
              <Select
                value={form.residentialStatus}
                onValueChange={setStr("residentialStatus")}
              >
                <SelectTrigger className="w-full">
                  <SelectValue placeholder="Select" />
                </SelectTrigger>
                <SelectContent>
                  {RESIDENTIAL_STATUS_OPTIONS.map((o) => (
                    <SelectItem key={o} value={o}>
                      {o}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>
            <FormField label="Time at Address">
              <div className="flex gap-2">
                <div className="flex items-center gap-1 flex-1">
                  <Input
                    type="number"
                    min={0}
                    value={form.timeAtAddressYears}
                    onChange={(e) =>
                      setStr("timeAtAddressYears")(e.target.value)
                    }
                    placeholder="0"
                  />
                  <span className="text-sm text-muted-foreground shrink-0">
                    yr
                  </span>
                </div>
                <div className="flex items-center gap-1 flex-1">
                  <Input
                    type="number"
                    min={0}
                    max={11}
                    value={form.timeAtAddressMonths}
                    onChange={(e) =>
                      setStr("timeAtAddressMonths")(e.target.value)
                    }
                    placeholder="0"
                  />
                  <span className="text-sm text-muted-foreground shrink-0">
                    mo
                  </span>
                </div>
              </div>
            </FormField>
          </div>

          {/* Previous address if < 2 years at current */}
          {parseInt(form.timeAtAddressYears || "99") < 2 && (
            <FormField label="Previous Address">
              <AddressAutocomplete
                value={form.previousAddress}
                onValueChange={setStr("previousAddress")}
                onSelect={(opt) => setStr("previousAddress")(opt.label)}
              />
            </FormField>
          )}

          {/* ID */}
          <div className="grid grid-cols-2 gap-4">
            <FormField label="Driver's Licence">
              <Input
                value={form.driversLicence}
                onChange={(e) => setStr("driversLicence")(e.target.value)}
                placeholder="e.g. 12345678"
              />
            </FormField>
            <FormField label="Passport Number">
              <Input
                value={form.passport}
                onChange={(e) => setStr("passport")(e.target.value)}
                placeholder="e.g. PA1234567"
              />
            </FormField>
          </div>

          {/* Financial structure */}
          <div className="grid grid-cols-2 gap-4">
            <FormField label="Property in Trust">
              <Select
                value={form.propertyInTrust}
                onValueChange={setStr("propertyInTrust")}
              >
                <SelectTrigger className="w-full">
                  <SelectValue placeholder="Select" />
                </SelectTrigger>
                <SelectContent>
                  {PROPERTY_IN_TRUST_OPTIONS.map((o) => (
                    <SelectItem key={o} value={o}>
                      {o}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>
            <FormField label="Company Ownership">
              <Select
                value={form.companyOwnership}
                onValueChange={setStr("companyOwnership")}
              >
                <SelectTrigger className="w-full">
                  <SelectValue placeholder="Select" />
                </SelectTrigger>
                <SelectContent>
                  {COMPANY_OWNERSHIP_OPTIONS.map((o) => (
                    <SelectItem key={o} value={o}>
                      {o}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>
          </div>
        </ModalScroll>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!isDirty}
            onClick={() => {
              onSave(form);
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// EditIncomeModal
// ---------------------------------------------------------------------------

export function EditIncomeModal({
  open,
  onOpenChange,
  applicantLabel = "Applicant",
  initialData,
  onSave,
  container,
  className,
}: EditIncomeModalProps) {
  const defaultItems = React.useMemo(
    () =>
      initialData?.items?.length
        ? initialData.items
        : [makeDefaultIncomeItem()],
    [], // eslint-disable-line react-hooks/exhaustive-deps
  );

  const [items, setItems] = React.useState<IncomeItem[]>(defaultItems);

  const initialSnapshot = React.useRef<string>("");

  React.useEffect(() => {
    if (open) {
      const data = initialData?.items?.length
        ? initialData.items
        : [makeDefaultIncomeItem()];
      setItems(data);
      initialSnapshot.current = JSON.stringify(data);
    }
  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps

  const isDirty = JSON.stringify(items) !== initialSnapshot.current;

  const updateItem = <K extends keyof IncomeItem>(
    id: string,
    key: K,
    val: IncomeItem[K],
  ) =>
    setItems((prev) =>
      prev.map((item) => (item.id === id ? { ...item, [key]: val } : item)),
    );

  const removeItem = (id: string) =>
    setItems((prev) => prev.filter((item) => item.id !== id));

  const addItem = () => setItems((prev) => [...prev, makeDefaultIncomeItem()]);

  const defaultOpenItems = items.length > 0 ? [items[0].id] : [];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent
        className={cn("max-w-lg", className)}
        container={container}
      >
        <DialogHeader>
          <DialogTitle>Edit Income {applicantLabel}</DialogTitle>
        </DialogHeader>
        <ModalScroll>
          <Accordion
            multiple
            defaultValue={defaultOpenItems}
            className="w-full"
          >
            {items.map((item, index) => (
              <AccordionItem key={item.id} value={item.id}>
                <AccordionItemHeader
                  label={`Income ${index + 1} — ${item.incomeType || "New Income"}`}
                  onRemove={() => removeItem(item.id)}
                  removeLabel="Remove income item"
                />
                <AccordionContent>
                  <div className="flex flex-col gap-4 pt-1">
                    <FormField label="Income Type">
                      <Select
                        value={item.incomeType}
                        onValueChange={(val) =>
                          updateItem(item.id, "incomeType", val ?? "")
                        }
                      >
                        <SelectTrigger className="w-full">
                          <SelectValue placeholder="Select type" />
                        </SelectTrigger>
                        <SelectContent>
                          {INCOME_TYPES.map((t) => (
                            <SelectItem key={t} value={t}>
                              {t}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </FormField>

                    <FormField label="Job Title">
                      <Input
                        value={item.jobTitle}
                        onChange={(e) =>
                          updateItem(item.id, "jobTitle", e.target.value)
                        }
                        placeholder="Job title"
                      />
                    </FormField>

                    <div className="grid grid-cols-2 gap-4">
                      <FormField label="Start Date">
                        <DatePicker
                          value={
                            item.startDate
                              ? new Date(item.startDate)
                              : undefined
                          }
                          onChange={(d) =>
                            updateItem(
                              item.id,
                              "startDate",
                              d ? d.toISOString().slice(0, 10) : "",
                            )
                          }
                          calendarProps={{
                            fromYear: 1950,
                            toYear: new Date().getFullYear(),
                          }}
                        />
                      </FormField>
                      {!item.stillInPosition && (
                        <FormField label="End Date">
                          <DatePicker
                            value={
                              item.endDate ? new Date(item.endDate) : undefined
                            }
                            onChange={(d) =>
                              updateItem(
                                item.id,
                                "endDate",
                                d ? d.toISOString().slice(0, 10) : "",
                              )
                            }
                            calendarProps={{
                              fromYear: 1950,
                              toYear: new Date().getFullYear(),
                            }}
                          />
                        </FormField>
                      )}
                    </div>

                    <div className="flex items-center gap-2">
                      <Checkbox
                        id={`still-in-position-${item.id}`}
                        checked={item.stillInPosition}
                        onCheckedChange={(checked) =>
                          updateItem(
                            item.id,
                            "stillInPosition",
                            checked === true,
                          )
                        }
                      />
                      <label
                        htmlFor={`still-in-position-${item.id}`}
                        className="text-sm cursor-pointer select-none"
                      >
                        Still in position
                      </label>
                    </div>

                    <FormField label="Company Name">
                      <Input
                        value={item.companyName}
                        onChange={(e) =>
                          updateItem(item.id, "companyName", e.target.value)
                        }
                        placeholder="Company name"
                      />
                    </FormField>

                    <FormField label="Company Address">
                      <AddressAutocomplete
                        value={item.companyAddress}
                        onValueChange={(val) =>
                          updateItem(item.id, "companyAddress", val)
                        }
                        placeholder="Search company address"
                      />
                    </FormField>

                    <div className="flex items-start gap-3">
                      <div className="flex-1">
                        <FormField label="Income Amount">
                          <CurrencyInputWithSlider
                            value={item.incomeAmount}
                            min={0}
                            max={1_000_000}
                            step={1_000}
                            onValueChange={(val) =>
                              updateItem(item.id, "incomeAmount", val)
                            }
                          />
                        </FormField>
                      </div>
                      <div className="shrink-0 mt-[1.625rem]">
                        <FrequencyToggle
                          value={item.frequency}
                          onValueChange={(val) =>
                            updateItem(item.id, "frequency", val)
                          }
                        />
                      </div>
                    </div>

                    <FormField label="Type of Company">
                      <RadioGroup
                        value={item.companyType}
                        onValueChange={(val) =>
                          updateItem(
                            item.id,
                            "companyType",
                            val as IncomeItem["companyType"],
                          )
                        }
                        className="flex gap-4"
                      >
                        {(["Public", "Private"] as const).map((opt) => (
                          <label
                            key={opt}
                            className="flex items-center gap-2 cursor-pointer text-sm"
                          >
                            <RadioGroupItem value={opt} />
                            {opt}
                          </label>
                        ))}
                      </RadioGroup>
                    </FormField>
                  </div>
                </AccordionContent>
              </AccordionItem>
            ))}
          </Accordion>

          <Button
            variant="outline"
            onClick={addItem}
            className="w-full gap-1.5"
          >
            <Plus className="h-4 w-4" />
            Add More
          </Button>
        </ModalScroll>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!isDirty}
            onClick={() => {
              onSave({ items });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// EditExpensesModal
// ---------------------------------------------------------------------------

export function EditExpensesModal({
  open,
  onOpenChange,
  applicantLabel = "Applicant",
  initialData,
  onSave,
  container,
  className,
}: EditExpensesModalProps) {
  const defaultItems = React.useMemo(
    () =>
      initialData?.items?.length
        ? initialData.items
        : [makeDefaultExpenseItem()],
    [], // eslint-disable-line react-hooks/exhaustive-deps
  );

  const [items, setItems] = React.useState<ExpenseItem[]>(defaultItems);

  const initialSnapshot = React.useRef<string>("");

  React.useEffect(() => {
    if (open) {
      const data = initialData?.items?.length
        ? initialData.items
        : [makeDefaultExpenseItem()];
      setItems(data);
      initialSnapshot.current = JSON.stringify(data);
    }
  }, [open]); // eslint-disable-line react-hooks/exhaustive-deps

  const isDirty = JSON.stringify(items) !== initialSnapshot.current;

  const updateItem = <K extends keyof ExpenseItem>(
    id: string,
    key: K,
    val: ExpenseItem[K],
  ) =>
    setItems((prev) =>
      prev.map((item) => (item.id === id ? { ...item, [key]: val } : item)),
    );

  const removeItem = (id: string) =>
    setItems((prev) => prev.filter((item) => item.id !== id));

  const addItem = () => setItems((prev) => [...prev, makeDefaultExpenseItem()]);

  const defaultOpenItems = items.length > 0 ? [items[0].id] : [];

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent
        className={cn("max-w-lg", className)}
        container={container}
      >
        <DialogHeader>
          <DialogTitle>Edit Expenses {applicantLabel}</DialogTitle>
        </DialogHeader>
        <ModalScroll>
          <Accordion
            multiple
            defaultValue={defaultOpenItems}
            className="w-full"
          >
            {items.map((item, index) => (
              <AccordionItem key={item.id} value={item.id}>
                <AccordionItemHeader
                  label={`Expense ${index + 1} — ${item.expenseType || "New Expense"}`}
                  onRemove={() => removeItem(item.id)}
                  removeLabel="Remove expense item"
                />
                <AccordionContent>
                  <div className="flex flex-col gap-4 pt-1">
                    <FormField label="Expense Type">
                      <Select
                        value={item.expenseType}
                        onValueChange={(val) =>
                          updateItem(item.id, "expenseType", val ?? "")
                        }
                      >
                        <SelectTrigger className="w-full">
                          <SelectValue placeholder="Select type" />
                        </SelectTrigger>
                        <SelectContent>
                          {EXPENSE_TYPES.map((t) => (
                            <SelectItem key={t} value={t}>
                              {t}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </FormField>

                    <div className="flex items-start gap-3">
                      <div className="flex-1">
                        <FormField label="Amount">
                          <CurrencyInputWithSlider
                            value={item.amount}
                            min={0}
                            max={100_000}
                            step={100}
                            onValueChange={(val) =>
                              updateItem(item.id, "amount", val)
                            }
                          />
                        </FormField>
                      </div>
                      <div className="shrink-0 mt-[1.625rem]">
                        <FrequencyToggle
                          value={item.frequency}
                          onValueChange={(val) =>
                            updateItem(item.id, "frequency", val)
                          }
                        />
                      </div>
                    </div>

                    <FormField label="Ownership (%)">
                      <OwnershipSplit
                        owners={[
                          {
                            id: "main",
                            name: "Main Applicant",
                            share: item.mainShare,
                          },
                          {
                            id: "co",
                            name: "Co-Applicant",
                            share: item.coShare,
                          },
                        ]}
                        onOwnersChange={(owners) => {
                          const main =
                            owners.find((o) => o.id === "main")?.share ??
                            item.mainShare;
                          const co =
                            owners.find((o) => o.id === "co")?.share ??
                            item.coShare;
                          updateItem(item.id, "mainShare", main);
                          updateItem(item.id, "coShare", co);
                        }}
                      />
                    </FormField>
                  </div>
                </AccordionContent>
              </AccordionItem>
            ))}
          </Accordion>

          <Button
            variant="outline"
            onClick={addItem}
            className="w-full gap-1.5"
          >
            <Plus className="h-4 w-4" />
            Add More
          </Button>
        </ModalScroll>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            disabled={!isDirty}
            onClick={() => {
              onSave({ items });
              onOpenChange(false);
            }}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
