// Chart-preview grouping for the setup wizard — reworked in Task 3 of
// docs/superpowers/plans/2026-08-02-chart-management.md (spec Part 3: the
// wizard preview relabels to the STANDARD terms — Assets / Liabilities /
// Equity / Income / Expenses — with the friendly one-liners as subtitles,
// not replacements; CLAUDE.md §9 as amended 2026-08-02). The account lists
// arrive from GET /api/setup/templates (one entry per industry template,
// each carrying its full chart INCLUDING subtype), so within each type the
// preview shows the same subtype sections the Chart of Accounts screen will
// show once the chart is stamped. Only account names are listed (CLAUDE.md
// §9 "Categories, not account numbers") — codes/types/subtypes exist to
// sort and group.

import {
  LEDGER_TYPES,
  SUBTYPES_BY_TYPE,
  SUBTYPE_LABELS,
  TYPE_HEADINGS,
  type LedgerType,
} from "../accounts/subtypes";

export interface PreviewAccount {
  code: string;
  name: string;
  type: string; // "asset" | "liability" | "equity" | "income" | "expense"
  subtype?: string | null;
}

/** One subtype section inside a type group. An empty label means "don't
 * show a section header" — the type heading directly above already says it
 * (a type whose accounts all fall in one section that just repeats the
 * heading, e.g. Equity). */
export interface PreviewSection {
  label: string;
  names: string[];
}

export interface PreviewGroup {
  heading: string;
  /** Friendly one-liner, rendered as a small subtitle under the heading. */
  subtitle: string;
  count: number;
  sections: PreviewSection[];
}

/** The plain-English layer ON TOP of the standard headings (amended §9's
 * example: "Assets — money you have and things you own"). */
export const TYPE_SUBTITLES: Readonly<Record<LedgerType, string>> = {
  asset: "money you have and things you own",
  liability: "money you owe",
  equity: "what's left for the owners",
  income: "money you earn",
  expense: "money you spend",
};

export function groupPreview(accounts: readonly PreviewAccount[]): PreviewGroup[] {
  const groups: PreviewGroup[] = [];
  for (const type of LEDGER_TYPES) {
    const ofType = accounts.filter((a) => a.type === type);
    if (ofType.length === 0) continue;
    const heading = TYPE_HEADINGS[type];
    // Same sectioning rules as accounts/pickerGroups.ts: subtype sections in
    // display order; untagged rows (subtype missing from the payload) under
    // the bare type heading, merged into a subtype section when that label
    // collides with the heading (equity).
    const collides = SUBTYPES_BY_TYPE[type].some((s) => SUBTYPE_LABELS[s] === heading);
    const sections: PreviewSection[] = SUBTYPES_BY_TYPE[type].map((s) => ({
      label: SUBTYPE_LABELS[s],
      names: ofType
        .filter((a) => a.subtype === s || (a.subtype == null && collides && SUBTYPE_LABELS[s] === heading))
        .map((a) => a.name),
    }));
    if (!collides) {
      sections.push({
        label: heading,
        names: ofType.filter((a) => a.subtype == null).map((a) => a.name),
      });
    }
    const nonEmpty = sections.filter((s) => s.names.length > 0);
    // A lone section whose label just repeats the type heading drops its
    // header ("Equity / Equity" would read twice).
    if (nonEmpty.length === 1 && nonEmpty[0]!.label === heading) {
      nonEmpty[0]!.label = "";
    }
    groups.push({
      heading,
      subtitle: TYPE_SUBTITLES[type],
      count: ofType.length,
      sections: nonEmpty,
    });
  }
  return groups;
}
