// Industry chart-of-accounts templates — Task 1 of
// docs/superpowers/plans/2026-08-02-chart-templates.md (design:
// docs/superpowers/specs/2026-08-02-chart-templates-design.md).
//
// A template is data only: the same row shape the original
// server/src/templates/small-business.ts used, plus picker copy (label,
// blurb, example account names) for the setup wizard's "What kind of work
// do you do?" step. Per CLAUDE.md §4 a template is only the starting stamp —
// every company gets its own private copy of the chart at creation and may
// diverge freely afterward.
//
// Every template = the shared spine (core.ts) + industry accounts. The spine
// carries every account a system FEATURE auto-finds by name or code
// (Accounts Receivable for ensure_ar_account(), Accounts Payable for
// ensure_ap_account(), Sales Tax Payable at 2200 for enable_sales_tax(),
// payroll wage/tax/liability accounts as ADP import targets), so those
// features behave identically no matter which industry the user picked.

export type LedgerType = "asset" | "liability" | "equity" | "income" | "expense";

/**
 * Presentation-and-grouping detail type (db/migrations/0016_account_subtypes.sql):
 * each subtype belongs to exactly one LedgerType, enforced by the accounts
 * table's CHECK matrix. SUBTYPES_BY_TYPE below is the same matrix as data.
 */
export type AccountSubtype =
  | "bank" | "accounts-receivable" | "other-current-asset" | "fixed-asset" | "other-asset"
  | "credit-card" | "line-of-credit" | "accounts-payable" | "other-current-liability" | "long-term-liability"
  | "equity"
  | "income" | "other-income"
  | "expense" | "cost-of-goods-sold" | "other-expense";

/** The type/subtype matrix — must mirror accounts_subtype_valid_for_type. */
export const SUBTYPES_BY_TYPE: Readonly<Record<LedgerType, readonly AccountSubtype[]>> =
  Object.freeze({
    asset: Object.freeze([
      "bank", "accounts-receivable", "other-current-asset", "fixed-asset", "other-asset",
    ] as const),
    liability: Object.freeze([
      "credit-card", "line-of-credit", "accounts-payable",
      "other-current-liability", "long-term-liability",
    ] as const),
    equity: Object.freeze(["equity"] as const),
    income: Object.freeze(["income", "other-income"] as const),
    expense: Object.freeze(["expense", "cost-of-goods-sold", "other-expense"] as const),
  });

export interface TemplateAccount {
  code: string;
  name: string;
  type: LedgerType;
  /** Required on every template row — new companies stamp fully-tagged charts. */
  subtype: AccountSubtype;
}

export interface ChartTemplate {
  /** Stable API key ('general', 'restaurant', ...) — what the create route accepts. */
  key: string;
  /** Picker card title, e.g. "General small business". */
  label: string;
  /** One plain-English sentence for the picker card — no accounting jargon (§9). */
  blurb: string;
  /** 2-3 distinctive account names shown on the card so the user recognizes their world. */
  examples: readonly string[];
  /** The full chart this template stamps into a new company, sorted by code. */
  accounts: readonly TemplateAccount[];
}

// The template modules import ONLY types from this file (`import type`, erased
// at compile time), so pulling their values back in here for the registry
// creates no runtime import cycle.
import { GENERAL_TEMPLATE } from "./small-business.js";
import {
  SERVICES_TEMPLATE,
  RETAIL_TEMPLATE,
  RESTAURANT_TEMPLATE,
  CONSTRUCTION_TEMPLATE,
  FIELD_SERVICES_TEMPLATE,
  PROPERTY_TEMPLATE,
  PRACTICE_TEMPLATE,
} from "./industries.js";

/** Every template, in picker display order — general (the default) first. */
export const CHART_TEMPLATES: readonly ChartTemplate[] = Object.freeze([
  GENERAL_TEMPLATE,
  SERVICES_TEMPLATE,
  RETAIL_TEMPLATE,
  RESTAURANT_TEMPLATE,
  CONSTRUCTION_TEMPLATE,
  FIELD_SERVICES_TEMPLATE,
  PROPERTY_TEMPLATE,
  PRACTICE_TEMPLATE,
]);

export const CHART_TEMPLATES_BY_KEY: ReadonlyMap<string, ChartTemplate> = new Map(
  CHART_TEMPLATES.map((t) => [t.key, t]),
);
