// SimVSM raw-file shapes (Wertstrom P6, KAR-878/KAR-986, execution-prompt
// §14). Derived from the confidential corpus SCHEMA only — every field/class
// name here is SimVSM's own generic tool vocabulary (also listed in §14.3's
// own examples), never a real customer/plant/product value. See README.md
// "Confidentiality" for the discipline that keeps it that way.
//
// Deliberately lenient/defensive: a real SimVSM export is a large,
// tool-generated GoJS document with many fields this importer never reads
// (viewState, measurementSeries, resultData, image assets, …) — every raw
// type below only names the fields this module actually consumes, and
// `parser.ts` never throws on an unrecognized shape (§14.2/11 "create no
// data before confirmation" implies parsing itself must be tolerant, the
// preview is where problems surface to the user).

/** One entry of a node's `parameters[]` array — SimVSM does NOT store node
 * parameters as a flat object, it stores an array of {class,type,value}
 * triples that must be looked up by `class` (see param-helpers.ts). */
export interface SimVsmParameter {
  class: string
  type?: string
  value?: unknown
}

/** A SimVSM canvas node. `category: 'item'` is a real VSM element (process/
 * inventory/customer/…); `category: 'text'` (and the shape/photo variants)
 * are canvas annotations — see mapping-registry.ts ANNOTATION_CLASSES. */
export interface SimVsmRawNode {
  key: number | string
  category?: string
  class?: string
  nodeName?: string
  loc?: string
  text?: string
  parameters?: SimVsmParameter[]
  photoNames?: string[]
}

export interface SimVsmRawLink {
  key?: number | string
  category?: string
  class?: string
  from?: number | string
  to?: number | string
  text?: string
}

export interface SimVsmRawModel {
  nodeDataArray?: SimVsmRawNode[]
  linkDataArray?: SimVsmRawLink[]
}

export interface SimVsmRawAlternative {
  name?: string
  isMain?: boolean
  model?: SimVsmRawModel
  modificationTime?: string
  lastOpenDate?: string
  resultData?: unknown[]
}

export interface SimVsmRawProduct {
  referenceId?: string
  name?: string
}

export interface SimVsmRawShiftCalendar {
  id?: number | string
  name?: string
}

export interface SimVsmRawSettings {
  products?: SimVsmRawProduct[]
  shiftCalendars?: SimVsmRawShiftCalendar[]
}

/** Top-level shape of one uploaded `.json` file. */
export interface SimVsmRawFile {
  name?: string
  description?: string
  createdWithVersion?: string
  mainVersion?: string
  alternatives?: SimVsmRawAlternative[]
  settings?: SimVsmRawSettings
  /** Present on most corpus files, undocumented by SimVSM itself — never
   * read, kept only so `Object.keys()` accounting in the parser can name it
   * as a known-but-unused top-level key rather than an "unknown" one. */
  resultView?: unknown
}

// ── Parser output ───────────────────────────────────────────────────────────

export interface SimVsmParsedNode {
  key: string
  /** 'item' (real VSM element) | 'text' | 'shape' | 'image' | other — drives
   * whether mapping-registry even attempts a VsmNode translation. */
  category: string
  simvsmClass: string
  nodeName: string
  /** Raw "x y" loc string, kept for diagnostics only — the importer never
   * trusts SimVSM coordinates directly (see streams.ts: positions are
   * recomputed via the existing vsm-auto-layout, not translated from `loc`,
   * because SimVSM's canvas is unbounded/can be negative while the editor's
   * world is not — a "visual layout difference", §14.4). */
  loc?: string
  text?: string
  params: Map<string, SimVsmParameter>
}

export interface SimVsmParsedLink {
  key: string
  simvsmClass: string
  fromKey: string
  toKey: string
  text?: string
}

export interface SimVsmParsedAlternative {
  index: number
  name: string
  isMainFlag: boolean
  nodes: SimVsmParsedNode[]
  links: SimVsmParsedLink[]
  hasResultData: boolean
  /** Raw ISO-ish timestamp string from SimVsmRawAlternative.modificationTime,
   * kept UNPARSED here (parsing/validity is the reader's job, see
   * streams.ts's resolveCurrentStreamIndex) — `undefined` when absent or not
   * a string, never a fabricated "now". Third-tier current-stream signal
   * (after isMain and the unsuffixed-name-prefix heuristic) and shown as
   * preview context (see preview.ts PreviewStream). */
  modificationTime?: string
}

export interface SimVsmParseIssue {
  code: string
  message: string
}

export interface SimVsmParsedFile {
  ok: true
  fileName: string
  modelName: string
  description: string
  createdWithVersion: string | null
  mainVersion: string | null
  productCount: number
  shiftCalendarCount: number
  alternatives: SimVsmParsedAlternative[]
  issues: SimVsmParseIssue[]
}

export interface SimVsmParseFailure {
  ok: false
  fileName: string
  error: string
}

export type SimVsmParseResult = SimVsmParsedFile | SimVsmParseFailure
