import type { PgTableWithColumns } from "drizzle-orm/pg-core";
import {
  landlordPropertyTypeOverrides,
  landlordBuiltFormTypeOverrides,
  landlordWallTypeOverrides,
  landlordRoofTypeOverrides,
  landlordMainFuelOverrides,
  landlordGlazingOverrides,
  landlordConstructionAgeBandOverrides,
  landlordWaterHeatingOverrides,
  landlordMainHeatingSystemOverrides,
  PropertyTypeValues,
  BuiltFormTypeValues,
  WallTypeValues,
  RoofTypeValues,
  MainFuelValues,
  GlazingValues,
  ConstructionAgeBandValues,
  WaterHeatingValues,
  MainHeatingSystemValues,
} from "@/app/db/schema/landlord_overrides";

// Single source of truth for the nine landlord-override categories. Adding a
// category here (alongside its schema table + value enum) wires it through the
// whole app layer at once: the read-only page, the verify/edit dropdowns, the
// Unknown finalise gate (ADR-0006), and user-edit validation. This registry
// replaces the per-category `switch` statements that previously had to be
// extended in ~6 places — a category defined in the schema but missing from one
// of those switches silently rendered as "not classified" (that is exactly what
// happened to the five non-core categories). The completeness test in
// categories.test.ts fails if this set ever drifts from CLASSIFIER_FIELDS or the
// value-enum exports.
//
// Order is display order (read-only page + verify panel) and intentionally
// mirrors CLASSIFIER_FIELDS. It is decoupled from the DB enum member order,
// which Postgres cannot reorder anyway — see docs/adr/0002.
export const LANDLORD_CATEGORIES = [
  "property_type",
  "built_form_type",
  "wall_type",
  "roof_type",
  "main_fuel",
  "glazing",
  "construction_age_band",
  "water_heating",
  "main_heating_system",
] as const;

export type LandlordOverrideCategory = (typeof LANDLORD_CATEGORIES)[number];

// Every landlord_*_overrides table is structurally identical — id, portfolio_id,
// description, value<per-category enum>, source, timestamps — differing only in
// the `value` enum's allowed strings. We deliberately erase that per-table enum
// type here so a single generic helper can serve all nine tables; the switches
// this registry replaced kept the typing, but every consumer already reads and
// writes `value` as a plain string and validates it against `values` at runtime.
// The `any` is confined to the table reference; `values` stays fully typed.
type LandlordOverrideTable = PgTableWithColumns<{
  name: string;
  schema: undefined;
  columns: any;
  dialect: "pg";
}>;

export interface CategoryConfig {
  table: LandlordOverrideTable;
  values: readonly string[];
}

export const CATEGORY_TABLES: Record<LandlordOverrideCategory, CategoryConfig> = {
  property_type: { table: landlordPropertyTypeOverrides, values: PropertyTypeValues },
  built_form_type: { table: landlordBuiltFormTypeOverrides, values: BuiltFormTypeValues },
  wall_type: { table: landlordWallTypeOverrides, values: WallTypeValues },
  roof_type: { table: landlordRoofTypeOverrides, values: RoofTypeValues },
  main_fuel: { table: landlordMainFuelOverrides, values: MainFuelValues },
  glazing: { table: landlordGlazingOverrides, values: GlazingValues },
  construction_age_band: {
    table: landlordConstructionAgeBandOverrides,
    values: ConstructionAgeBandValues,
  },
  water_heating: { table: landlordWaterHeatingOverrides, values: WaterHeatingValues },
  main_heating_system: {
    table: landlordMainHeatingSystemOverrides,
    values: MainHeatingSystemValues,
  },
};

// Valid enum values per category — populates the verify-panel edit dropdowns
// (client) and validates a user correction (server). Derived from the registry
// so it can never drift from the table set.
export const CATEGORY_VALUES: Record<LandlordOverrideCategory, readonly string[]> =
  Object.fromEntries(
    LANDLORD_CATEGORIES.map((category) => [category, CATEGORY_TABLES[category].values]),
  ) as Record<LandlordOverrideCategory, readonly string[]>;

export function isLandlordCategory(field: string): field is LandlordOverrideCategory {
  return field in CATEGORY_TABLES;
}
