// ─── Value objects ────────────────────────────────────────────────────────────

export interface MasterRecord {
  id: string;
  name: string;
  code: string | null;
  description: string | null;
  isActive: boolean;
  sortOrder: number;
  metadata: Record<string, unknown>;
  effectiveFrom: string;
  effectiveTo: string | null;
  createdAt: string;
  createdBy: string | null;
  updatedAt: string | null;
  updatedBy: string | null;
  // Hierarchical (only present when hierarchical: true)
  parentId?: string | null;
  path?: string | null;
  depth?: number | null;
  // mst_area extras
  areaType?: string | null;
  // mst_company extras
  ownerId?: string | null;
  // mst_incident_type extras
  groupId?: string | null;
}

export interface MasterFilter {
  q?: string;
  parentId?: string;
  isActive?: boolean;
  page: number;
  limit: number;
}

export interface MasterPage {
  items: MasterRecord[];
  total: number;
  page: number;
  limit: number;
}

export interface CreateMasterInput {
  name: string;
  code?: string;
  description?: string;
  sortOrder?: number;
  isActive?: boolean;
  metadata?: Record<string, unknown>;
  effectiveFrom?: string;
  effectiveTo?: string;
  // Hierarchical
  parentId?: string;
  // Domain-specific
  ownerId?: string;
  groupId?: string;
  path?: string;
  depth?: number;
  areaType?: string;
}

export interface UpdateMasterInput {
  name?: string;
  code?: string;
  description?: string;
  sortOrder?: number;
  isActive?: boolean;
  metadata?: Record<string, unknown>;
  effectiveFrom?: string;
  effectiveTo?: string;
  // Hierarchical
  parentId?: string;
  // Domain-specific
  ownerId?: string;
  groupId?: string;
  path?: string;
  depth?: number;
  areaType?: string;
}

// ─── Domain configuration ─────────────────────────────────────────────────────

export interface DomainConfig {
  table: string;
  hierarchical: boolean;
  extraCols?: string[];
  /** Column holding the human-readable name — defaults to "name", some tables use "label" */
  nameCol?: string;
  /** Tables that lack created_by / updated_by columns */
  noAuditCols?: boolean;
  /** Tables that lack is_active (e.g. mst_answer_type uses status text) */
  noIsActive?: boolean;
  /** Tables that lack updated_at (e.g. mst_person_role_type) */
  noUpdatedAt?: boolean;
}

/**
 * Registry of all supported master-data domains.
 * ALL SQL table names are resolved from this map — never from user input.
 */
export const DOMAIN_REGISTRY: Map<string, DomainConfig> = new Map([
  ["country",              { table: "master.mst_country",             hierarchical: false }],
  ["company",              { table: "master.mst_company",             hierarchical: false }],
  ["organisation",         { table: "master.mst_organisation",        hierarchical: false }],
  ["business-unit",        { table: "master.mst_business_unit",       hierarchical: false }],
  ["department",           { table: "master.mst_department",          hierarchical: false }],
  ["entity",               { table: "master.mst_entity",              hierarchical: false }],
  ["area",                 { table: "master.mst_area",                hierarchical: true,  extraCols: ["parent_id", "path", "depth", "area_type"] }],
  ["incident-type",        { table: "master.mst_incident_type",       hierarchical: false, extraCols: ["group_id"] }],
  ["incident-group",       { table: "master.mst_incident_group",      hierarchical: false }],
  ["incident-sub-type",    { table: "master.mst_incident_sub_type",   hierarchical: false }],
  ["person-role-type",     { table: "master.mst_person_role_type",    hierarchical: false, noAuditCols: true, noUpdatedAt: true }],
  ["suggestion-group",     { table: "master.mst_suggestion_group",    hierarchical: false }],
  ["priority",             { table: "master.mst_priority",            hierarchical: false, nameCol: "label", noAuditCols: true }],
  ["severity",             { table: "master.mst_severity",            hierarchical: false, nameCol: "label", noAuditCols: true }],
  ["likelihood",           { table: "master.mst_likelihood",          hierarchical: false, nameCol: "label", noAuditCols: true }],
  ["uom",                  { table: "master.mst_uom",                 hierarchical: false, noAuditCols: true }],
  ["currency",             { table: "master.mst_currency",            hierarchical: false, noAuditCols: true }],
  ["speciality",           { table: "master.mst_speciality",          hierarchical: false, noAuditCols: true }],
  ["root-cause-category",  { table: "master.mst_root_cause_category", hierarchical: false, nameCol: "label", noAuditCols: true }],
  ["symptoms",             { table: "master.mst_symptoms",            hierarchical: false }],
  ["modules",              { table: "master.mst_modules",             hierarchical: false }],
  ["answer-type",          { table: "master.mst_answer_type",         hierarchical: false, noAuditCols: true, noIsActive: true }],
]);

export function resolveDomain(domain: string): DomainConfig {
  const cfg = DOMAIN_REGISTRY.get(domain);
  if (!cfg) {
    const validDomains = [...DOMAIN_REGISTRY.keys()].join(", ");
    throw new Error(
      `Unknown master-data domain "${domain}". Valid domains: ${validDomains}`
    );
  }
  return cfg;
}

// ─── Repository interface ─────────────────────────────────────────────────────

export interface MasterRepository {
  list(domain: string, filter: MasterFilter): Promise<MasterPage>;
  getById(domain: string, id: string): Promise<MasterRecord | null>;
  create(domain: string, data: CreateMasterInput): Promise<MasterRecord>;
  update(domain: string, id: string, data: UpdateMasterInput): Promise<MasterRecord | null>;
  softDelete(domain: string, id: string): Promise<boolean>;
}
