// Shared types for the canonical QAF field model (KAR-892 / P1.1).
//
// Split out from canonical-model.ts so the pure data file (canonical-fields.ts)
// can import just the types without creating a data <-> access-function
// circular import (canonical-model.ts imports the CANONICAL_FIELDS constant
// from canonical-fields.ts; canonical-fields.ts only needs the types, not the
// access functions).
//
// tdd-guard:skip — type declarations only, no logic (same category as types.ts).

/**
 * The eleven QAF-9.1 module names (Master-Prompt §6, backlog P1.1) plus G60 —
 * G60 is a structurally distinct detail-QAF workbook (112-tab, coordinate-
 * addressed, see internal/g60/) rather than a sheet within the standard QAF,
 * but it carries the same kind of field vocabulary and needs the same
 * registry treatment, so it is modeled as a twelfth module here rather than
 * bolted on separately.
 */
export type QafModule =
  | "SUMMARY"
  | "MANUFACTURING"
  | "MATERIAL"
  | "SBM"
  | "LOGISTICS"
  | "RMR"
  | "LC_CN"
  | "CO2E"
  | "WAF"
  | "LAF"
  | "LEK"
  | "G60"

/** Field data type, independent of how a given sheet renders it (Dropdown/Freitext/etc.). */
export type CanonicalDataType =
  | "text"
  | "freetext"
  | "number"
  | "percent"
  | "currency"
  | "date"
  | "month_year"
  | "dropdown"
  | "boolean"
  | "image"

/**
 * Master-Prompt §6 classification: whether the SUPPLIER types the value in
 * (`input`), Excel derives it from a formula (`calculated`), it is written
 * once by BMW and locked for the supplier (`protected`), or it exists purely // allow-customer-string
 * for context/readability with no comparison semantics (`informational`).
 */
export type CanonicalClassification =
  | "input"
  | "calculated"
  | "protected"
  | "informational"

/**
 * Fehlerreport-derived "notwendig"/mandatory classification (see
 * rule-engine.ts R2/R3, which this registry is the eventual source-of-truth
 * replacement for — P0.4 interim hardcoded list migrates here in a later PR,
 * NOT this one, see canonical-fields.ts header).
 *   - mandatory: comparison-critical, R2 applies (Pflichtfeld-Blockade).
 *   - conditional: mandatory only once a sibling field/dropdown is set
 *     (e.g. SBM "Werkzeug-/Vorrichtungsart" only after "Verrechnungsform").
 *   - optional: R3 applies at most (warn, never blocks).
 */
export type CanonicalRequirement = "mandatory" | "conditional" | "optional"

/** Whether one instance of the field exists per detail row, or once per file/summary block. */
export type CanonicalLevel = "row" | "summary"

/**
 * One source-evidence reference. `source` is a short, greppable pointer —
 * "leitfaden-teil1:18" means brain/01-Projekte/supplierpulse-qaf-adaptive-
 * engine/02-leitfaden-teil1.md, Leitfaden page marker [18]; "code:qaf-
 * parser.ts:HEADER_TO_KEY" points at an existing, already-shipped mapping;
 * "fehlerreport-analyse:3.3" points at 03-fehlerreport-analyse.md section
 * 3.3. Kept as a plain string (not a URL/enum) because the evidence base is
 * a fixed, small set of brain documents + this repo — a stable convention is
 * enough, a schema would be over-engineering for ~200 entries.
 */
export interface CanonicalFieldEvidence {
  source: string
  note?: string
}

export interface CanonicalField {
  /** Stable, English, snake_case, module-prefixed (e.g. "mfg_manufacturing_cost_aw"). Never renamed once shipped — see canonical-fields.ts header. */
  id: string
  module: QafModule
  /** Sheet sub-section / table name from the Leitfaden (e.g. "Feldtabelle Teil 1", "Rohstoffdetaillierung"). Free text, not an enum — sections are numerous and module-specific. */
  section: string
  labelDe: string
  labelEn: string
  /**
   * Additional known label variants beyond labelDe/labelEn: documented BMW // allow-customer-string
   * source typos ("Teilebennung", "Mengeneinheit" duplicate, G60's "Raw
   * material sucharge"), older template wordings, etc. Checked by
   * findByAlias() alongside labelDe/labelEn.
   */
  aliases: string[]
  dataType: CanonicalDataType
  /** Free-text unit/dimension as written in the Leitfaden ("BW/h", "AW/kg", "%", "kg", "mm", ...), or undefined for non-quantified fields. */
  unit?: string
  classification: CanonicalClassification
  requirement: CanonicalRequirement
  level: CanonicalLevel
  /**
   * QAF template versions this field is confirmed to exist in, e.g.
   * ["V8_EN", "V9_DE", "V9.1_DE", "V9.1_EN"]. Free-text tokens (not an enum)
   * because the exact version lineage is only partially documented — see
   * canonical-fields.ts header for what's verified vs. assumed.
   */
  templateVersions: string[]
  evidence: CanonicalFieldEvidence[]
  /**
   * Set ONLY when this field's label deliberately collides with another
   * field's label in the same module (documented BMW source-data duplicate, // allow-customer-string
   * not a registry bug) — both/all colliding entries must share the exact
   * same string. validateRegistry() enforces that any label collision within
   * a module either has a shared collisionGroup or is reported as an error.
   */
  collisionGroup?: string
  notes?: string
}

export interface RegistryValidationResult {
  ok: boolean
  errors: string[]
}
