import { useQuery } from "@tanstack/react-query";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { listAccounts } from "@/lib/erp";

type AccountRow = {
  id: string;
  code: string;
  name: string;
  parent_id: string | null;
  is_active: boolean;
  is_system: boolean;
  balance_locked: boolean;
  account_types: { code: string; category: string } | null;
};


export function useAccounts() {
  return useQuery({
    queryKey: ["accounts"],
    queryFn: async () => (await listAccounts()) as unknown as AccountRow[],
  });
}

/**
 * Accounts available for posting, filtered by account-type code.
 * Heading and control accounts (is_system) are hidden — the engine posts to
 * those itself, users pick the detail accounts underneath them.
 */
export function useAccountsByType(typeCodes?: string[], includeSystem = false, excludeLocked = false) {
  const q = useAccounts();
  const all = q.data ?? [];
  const parentIds = new Set(
    all.map((a) => (a as unknown as { parent_id: string | null }).parent_id).filter(Boolean) as string[],
  );
  const rows = all.filter(
    (a) =>
      a.is_active &&
      (includeSystem || (!a.is_system && !parentIds.has(a.id))) &&
      (!excludeLocked || !a.balance_locked) &&
      (!typeCodes || typeCodes.includes(a.account_types?.code ?? "")),
  );
  return { ...q, accounts: rows };
}


export function AccountSelect({
  value,
  onChange,
  typeCodes,
  placeholder = "Select account",
  id,
  includeSystem = false,
  excludeLocked = false,
}: {
  value: string | null;
  onChange: (id: string) => void;
  typeCodes?: string[];
  placeholder?: string;
  id?: string;
  /** Set for read-only filters (e.g. ledger drill-down) where control accounts matter. */
  includeSystem?: boolean;
  /** Hide accounts whose balance is read-only (only reversals may change them). */
  excludeLocked?: boolean;
}) {
  const { accounts } = useAccountsByType(typeCodes, includeSystem, excludeLocked);
  return (
    <Select value={value ?? ""} onValueChange={onChange}>
      <SelectTrigger id={id}>
        <SelectValue placeholder={placeholder} />
      </SelectTrigger>
      <SelectContent>
        {accounts.map((a) => (
          <SelectItem key={a.id} value={a.id}>
            {a.code} · {a.name}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

/** Simple generic id/label select used across module forms. */
export function EntitySelect({
  value,
  onChange,
  options,
  placeholder = "Select",
  id,
}: {
  value: string | null;
  onChange: (id: string) => void;
  options: { value: string; label: string }[];
  placeholder?: string;
  id?: string;
}) {
  return (
    <Select value={value ?? ""} onValueChange={onChange}>
      <SelectTrigger id={id}>
        <SelectValue placeholder={placeholder} />
      </SelectTrigger>
      <SelectContent>
        {options.map((o) => (
          <SelectItem key={o.value} value={o.value}>
            {o.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

/**
 * Options for catalogue forms that map an item to the revenue account it posts to.
 * Only detail (leaf) revenue accounts are offered — heading accounts such as
 * "4000 Studio Revenue" must not receive postings directly.
 */
export function useRevenueAccountOptions() {
  const { accounts } = useAccountsByType(["REVENUE"]);
  return accounts.map((a) => ({ value: a.id, label: `${a.code} · ${a.name}` }));
}
