// Lookup helpers over a parsed node's `parameters[]` array (see types.ts doc
// comment on SimVsmParsedNode.params — SimVSM stores parameters as an array
// of {class,type,value} triples, not a flat object). Every helper is
// tolerant: a missing/mistyped parameter returns `undefined`, never throws —
// the corpus scan (schema_scan, local-only) found the SAME parameter class
// (e.g. ShiftCalendar, MTTR, OrderTptTime_HistInterval) stored as a bare
// number OR as `{durationInSec}` OR entirely absent across different files,
// so every reader here defends against all three.

import type { SimVsmParameter } from './types'

export function paramValue(params: Map<string, SimVsmParameter>, cls: string): unknown {
  return params.get(cls)?.value
}

/** SimVSM time values are usually `{durationInSec: number, stopwatch?: bool}`
 * but appear as a bare number in some files (schema_scan finding) — both
 * read as seconds. Returns `undefined` (never 0) when absent, so a caller
 * never fabricates a zero duration (§14.2 "never overwrite/invent silently"
 * applied to reads, not just writes). */
export function paramDurationSec(params: Map<string, SimVsmParameter>, cls: string): number | undefined {
  const v = paramValue(params, cls)
  if (typeof v === 'number' && Number.isFinite(v)) return v
  if (v && typeof v === 'object' && 'durationInSec' in v) {
    const raw = (v as { durationInSec?: unknown }).durationInSec
    return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined
  }
  return undefined
}

export function paramNumber(params: Map<string, SimVsmParameter>, cls: string): number | undefined {
  const v = paramValue(params, cls)
  return typeof v === 'number' && Number.isFinite(v) ? v : undefined
}

export function paramBoolean(params: Map<string, SimVsmParameter>, cls: string): boolean | undefined {
  const v = paramValue(params, cls)
  return typeof v === 'boolean' ? v : undefined
}

export function paramString(params: Map<string, SimVsmParameter>, cls: string): string | undefined {
  const v = paramValue(params, cls)
  if (typeof v !== 'string') return undefined
  const trimmed = v.trim()
  return trimmed.length > 0 ? trimmed : undefined
}

/** `ProductTable`/`Produkte`-style `{rows: [...]}` tableGrid parameter.
 * Only the FIRST row is read anywhere in this module (deliberate
 * single-product simplification — see mapping-registry.ts and README.md
 * "Multi-Produkt"), never all rows. */
export function paramFirstTableRow(params: Map<string, SimVsmParameter>, cls: string): Record<string, unknown> | undefined {
  const v = paramValue(params, cls)
  if (!v || typeof v !== 'object' || !('rows' in v)) return undefined
  const rows = (v as { rows?: unknown }).rows
  if (!Array.isArray(rows) || rows.length === 0) return undefined
  const first = rows[0]
  return first && typeof first === 'object' ? (first as Record<string, unknown>) : undefined
}

export function rowDurationSec(row: Record<string, unknown> | undefined, key: string): number | undefined {
  if (!row) return undefined
  const v = row[key]
  if (typeof v === 'number' && Number.isFinite(v)) return v
  if (v && typeof v === 'object' && 'durationInSec' in v) {
    const raw = (v as { durationInSec?: unknown }).durationInSec
    return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined
  }
  return undefined
}

export function rowNumber(row: Record<string, unknown> | undefined, key: string): number | undefined {
  if (!row) return undefined
  const v = row[key]
  return typeof v === 'number' && Number.isFinite(v) ? v : undefined
}
