// The seven industry chart templates — Task 1 of
// docs/superpowers/plans/2026-08-02-chart-templates.md. Each is the shared
// spine (core.ts) plus 8-20 industry accounts drawn from standard
// small-business chart-of-accounts practice for that industry, with
// plain-English names a non-accountant recognizes (CLAUDE.md §9 —
// "Delivery Platform Fees", not "Commissions - 3rd party").
//
// Kind choices that matter (the schema has exactly five kinds — see core.ts):
//   - Money held for someone else is a LIABILITY: Tips Payable, Security
//     Deposits Held, Gift Cards Outstanding, Client Retainers Held (money
//     received before it is earned), Customer Deposits Held, Client Trust
//     Obligations.
//   - Money someone is holding back from you is an ASSET: Retainage
//     Receivable (the % a customer keeps until the job is accepted), Client
//     Trust Account (the bank account matching the trust liability).
//   - Sales Returns/Refunds and Discounts Given are INCOME accounts that
//     normally carry a negative balance (contra-income) — the schema has no
//     contra concept, so QB-convention: income kind, clarifying name.
//   - Direct costs of what you sell live in the 5xxx bucket as `expense`
//     rows (no separate COGS kind), keeping them visually separate from
//     the 6xxx overhead block on every report ordered by code.
//
// Code ranges are documented in core.ts; nothing here may touch a spine code.

import type { ChartTemplate } from "./types.js";
import { composeChart } from "./core.js";

export const SERVICES_TEMPLATE: ChartTemplate = Object.freeze({
  key: "services",
  label: "Services and consulting",
  blurb: "Consulting, freelancing, design, or agency work billed to clients.",
  examples: Object.freeze(["Project Income", "Retainer Income", "Subcontracted Work"]),
  accounts: composeChart([
    { code: "2500", name: "Client Deposits Held", type: "liability", subtype: "other-current-liability" },
    { code: "4000", name: "Project Income", type: "income", subtype: "income" },
    { code: "4010", name: "Retainer Income", type: "income", subtype: "income" },
    { code: "4030", name: "Reimbursed Client Expenses", type: "income", subtype: "income" },
    { code: "5000", name: "Subcontracted Work", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5010", name: "Project Supplies and Materials", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "6300", name: "Website and Hosting", type: "expense", subtype: "expense" },
    { code: "6310", name: "Freelance Platform Fees", type: "expense", subtype: "expense" },
  ]),
});

export const RETAIL_TEMPLATE: ChartTemplate = Object.freeze({
  key: "retail",
  label: "Retail and online sales",
  blurb: "Selling products, whether in a shop or online.",
  examples: Object.freeze(["Product Sales", "Inventory", "Card Processing Fees"]),
  accounts: composeChart([
    // Inventory is a chart account only — no valuation machinery, no items
    // (deferred per CLAUDE.md §5; same as QB's chart-only treatment).
    { code: "1300", name: "Inventory", type: "asset", subtype: "other-current-asset" },
    { code: "2500", name: "Gift Cards Outstanding", type: "liability", subtype: "other-current-liability" },
    { code: "4000", name: "Product Sales", type: "income", subtype: "income" },
    { code: "4030", name: "Sales Returns and Refunds", type: "income", subtype: "income" },
    { code: "4040", name: "Discounts Given", type: "income", subtype: "income" },
    { code: "4050", name: "Shipping Income", type: "income", subtype: "income" },
    { code: "5000", name: "Cost of Goods Sold", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5010", name: "Shipping on Purchases", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "6300", name: "Card Processing Fees", type: "expense", subtype: "expense" },
    { code: "6310", name: "Shipping to Customers", type: "expense", subtype: "expense" },
    { code: "6320", name: "Store Supplies and Packaging", type: "expense", subtype: "expense" },
    { code: "6330", name: "Online Marketplace Fees", type: "expense", subtype: "expense" },
  ]),
});

export const RESTAURANT_TEMPLATE: ChartTemplate = Object.freeze({
  key: "restaurant",
  label: "Restaurant and food service",
  blurb: "Restaurants, cafes, bars, food trucks, and catering.",
  examples: Object.freeze(["Food Sales", "Tips Payable", "Delivery Platform Fees"]),
  accounts: composeChart([
    { code: "1300", name: "Food and Beverage Inventory", type: "asset", subtype: "other-current-asset" },
    { code: "2500", name: "Tips Payable", type: "liability", subtype: "other-current-liability" },
    { code: "2510", name: "Gift Cards Outstanding", type: "liability", subtype: "other-current-liability" },
    { code: "4000", name: "Food Sales", type: "income", subtype: "income" },
    { code: "4010", name: "Beverage Sales", type: "income", subtype: "income" },
    { code: "4030", name: "Catering Income", type: "income", subtype: "income" },
    { code: "5000", name: "Food Purchases", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5010", name: "Beverage Purchases", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "6300", name: "Kitchen Supplies", type: "expense", subtype: "expense" },
    { code: "6310", name: "Delivery Platform Fees", type: "expense", subtype: "expense" },
    { code: "6320", name: "Card Processing Fees", type: "expense", subtype: "expense" },
    { code: "6330", name: "Linens and Uniforms", type: "expense", subtype: "expense" },
  ]),
});

export const CONSTRUCTION_TEMPLATE: ChartTemplate = Object.freeze({
  key: "construction",
  label: "Construction and trades",
  blurb: "Building, remodeling, and contracting jobs.",
  examples: Object.freeze(["Contract Income", "Job Materials", "Retainage Receivable"]),
  accounts: composeChart([
    // Retainage: the slice of each progress payment the customer holds back
    // until the job is accepted — money owed to you, hence an asset.
    { code: "1300", name: "Retainage Receivable", type: "asset", subtype: "other-current-asset" },
    { code: "2500", name: "Customer Deposits Held", type: "liability", subtype: "other-current-liability" },
    { code: "4000", name: "Contract Income", type: "income", subtype: "income" },
    { code: "4010", name: "Change Order Income", type: "income", subtype: "income" },
    { code: "5000", name: "Job Materials", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5010", name: "Subcontractors", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5020", name: "Equipment Rental", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5030", name: "Permits and Inspection Fees", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "6300", name: "Small Tools and Equipment", type: "expense", subtype: "expense" },
    { code: "6310", name: "Fuel", type: "expense", subtype: "expense" },
  ]),
});

export const FIELD_SERVICES_TEMPLATE: ChartTemplate = Object.freeze({
  key: "field-services",
  label: "Field services",
  blurb: "Landscaping, cleaning, repairs, and other work done at the customer's place.",
  examples: Object.freeze(["Service Income", "Fuel", "Route Supplies"]),
  accounts: composeChart([
    { code: "4000", name: "Service Income", type: "income", subtype: "income" },
    { code: "4010", name: "Recurring Service Plans", type: "income", subtype: "income" },
    { code: "5000", name: "Job Materials and Parts", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "5010", name: "Subcontracted Help", type: "expense", subtype: "cost-of-goods-sold" },
    { code: "6300", name: "Fuel", type: "expense", subtype: "expense" },
    { code: "6310", name: "Vehicle Repairs and Tires", type: "expense", subtype: "expense" },
    { code: "6320", name: "Route Supplies", type: "expense", subtype: "expense" },
    { code: "6330", name: "Small Equipment and Tools", type: "expense", subtype: "expense" },
    { code: "6340", name: "Uniforms", type: "expense", subtype: "expense" },
    { code: "6350", name: "Equipment Rental", type: "expense", subtype: "expense" },
  ]),
});

export const PROPERTY_TEMPLATE: ChartTemplate = Object.freeze({
  key: "property",
  label: "Rental property",
  blurb: "Renting out or managing houses, apartments, or commercial space.",
  examples: Object.freeze(["Rental Income", "Security Deposits Held", "Mortgage Interest"]),
  accounts: composeChart([
    { code: "1300", name: "Buildings and Improvements", type: "asset", subtype: "fixed-asset" },
    { code: "1310", name: "Land", type: "asset", subtype: "fixed-asset" },
    // Tenant deposits are the tenant's money until move-out — a liability.
    { code: "2500", name: "Security Deposits Held", type: "liability", subtype: "other-current-liability" },
    { code: "4000", name: "Rental Income", type: "income", subtype: "income" },
    { code: "4010", name: "Late Fee Income", type: "income", subtype: "income" },
    { code: "4030", name: "Application Fee Income", type: "income", subtype: "income" },
    { code: "6300", name: "Property Management Fees", type: "expense", subtype: "expense" },
    { code: "6310", name: "Property Taxes", type: "expense", subtype: "expense" },
    { code: "6320", name: "Mortgage Interest", type: "expense", subtype: "expense" },
    { code: "6330", name: "Landscaping and Snow Removal", type: "expense", subtype: "expense" },
    { code: "6340", name: "Cleaning and Turnover", type: "expense", subtype: "expense" },
    { code: "6350", name: "HOA Dues", type: "expense", subtype: "expense" },
  ]),
});

export const PRACTICE_TEMPLATE: ChartTemplate = Object.freeze({
  key: "practice",
  label: "Professional practice",
  blurb: "A medical, dental, legal, accounting, or similar professional practice.",
  examples: Object.freeze([
    "Client and Patient Fees",
    "Client Retainers Held",
    "Professional Liability Insurance",
  ]),
  accounts: composeChart([
    // Trust/IOLTA money is the client's: the bank account is an asset with a
    // matching liability, so holding it never looks like practice income.
    // Chart accounts ONLY — this software provides no trust-compliance
    // features (no three-way reconciliation of bank vs. book vs. per-client
    // ledgers); the pair just gives trust money a correct home.
    // The trust account is a real bank account (it holds client money at a
    // bank) — subtype `bank` so it appears with the other money accounts.
    { code: "1300", name: "Client Trust Account", type: "asset", subtype: "bank" },
    { code: "2500", name: "Client Retainers Held", type: "liability", subtype: "other-current-liability" },
    { code: "2510", name: "Client Trust Obligations", type: "liability", subtype: "other-current-liability" },
    { code: "4000", name: "Client and Patient Fees", type: "income", subtype: "income" },
    { code: "4010", name: "Insurance Reimbursements", type: "income", subtype: "income" },
    { code: "6300", name: "Professional Liability Insurance", type: "expense", subtype: "expense" },
    { code: "6310", name: "Professional Licenses", type: "expense", subtype: "expense" },
    { code: "6320", name: "Reference Materials and Research", type: "expense", subtype: "expense" },
    { code: "6330", name: "Billing and Collection Fees", type: "expense", subtype: "expense" },
  ]),
});
