// Pure Excel-row mapping for the VSM editor's "Excel importieren" flow.
// The Excel file read itself still lives in the component (binds to a File
// from an input element); only the post-parse row→preview mapping is here.

import type { VsmConnection, VsmNode } from '@/lib/vsm-types'

export interface VsmImportRow {
  name: string
  cycleTimeSec: number | undefined
  machineTimeSec: number | undefined
  manualTimeSec: number | undefined
  setupTimeSec: number | undefined
  waitTimeSec: number | undefined
}

/**
 * Review-Fix F3 (adversarial review, Wertstrom P0): an empty Excel cell and
 * a real `0` must stay distinguishable all the way through — the Zod
 * schema (lib/api/schemas.ts VsmNodeSchema) treats 0 as a valid boundary
 * ("0s Rüstzeit" is real data), never as "unknown". The caller
 * (vsm-editor.tsx handleExcelFile) already normalizes a missing cell to
 * `null` (`cell.value ?? null`); this also tolerates `undefined` and an
 * empty/whitespace-only string cell the same way. `Number(row[...] ?? 0)`
 * used to collapse ALL of these — empty cell AND a genuine `0` cell — to
 * the same `0`, making them indistinguishable before they even left this
 * function.
 */
// Wertstrom P4 (A14, KAR-878/KAR-986): exported — the new Tabellen-View's
// Excel-Paste (vsm-table-paste.ts) reuses this exact nullish-vs-falsy
// parsing instead of re-implementing it, per the P4-Brief's explicit
// instruction ("dessen numericCellOrUndefined WIEDERVERWENDEN"). Behavior
// is unchanged — only the export keyword was added.
export function numericCellOrUndefined(raw: unknown): number | undefined {
  if (raw === undefined || raw === null) return undefined
  if (typeof raw === 'string' && raw.trim() === '') return undefined
  const n = Number(raw)
  return Number.isNaN(n) ? undefined : n
}

export function mapExcelRowsToPreview(rows: Record<string, unknown>[]): VsmImportRow[] {
  return rows
    .map((row) => ({
      name: String(row['Prozessschritt'] ?? row['Name'] ?? ''),
      cycleTimeSec: numericCellOrUndefined(row['Zykluszeit']),
      machineTimeSec: numericCellOrUndefined(row['Maschinenzeit']),
      manualTimeSec: numericCellOrUndefined(row['Manuelle Zeit']),
      setupTimeSec: numericCellOrUndefined(row['Rüstzeit']),
      waitTimeSec: numericCellOrUndefined(row['Wartezeit']),
    }))
    .filter((r) => r.name)
}

/**
 * Review-Fix F3, apply-level: maps a preview row directly onto the VsmNode
 * time fields applyExcelImport (vsm-editor.tsx) writes — nullish, not
 * falsy. The preview row already carries `undefined` for a genuinely empty
 * cell and a real number (including `0`) otherwise (see
 * mapExcelRowsToPreview above); this must not re-introduce the same bug by
 * falsy-coalescing (`row.x || undefined`) on the way into the node. Pulled
 * out as its own pure/testable function, sibling to
 * buildLinearConnectionPairs, rather than left as inline mapping in the
 * component.
 */
export function importRowToNodeTimeFields(
  row: VsmImportRow,
): Pick<VsmNode, 'cycleTimeSec' | 'machineTimeSec' | 'manualTimeSec' | 'setupTimeSec' | 'waitTimeSec'> {
  return {
    cycleTimeSec: row.cycleTimeSec ?? undefined,
    machineTimeSec: row.machineTimeSec ?? undefined,
    manualTimeSec: row.manualTimeSec ?? undefined,
    setupTimeSec: row.setupTimeSec ?? undefined,
    waitTimeSec: row.waitTimeSec ?? undefined,
  }
}

/**
 * Wertstrom P0 (KAR-878): linear i→i+1 connection pairs for a freshly
 * imported node chain — same topology the LSC import (vsm-editor.tsx
 * handleLscImport) and the QAF mapper
 * (lib/qaf-value-stream/internal/mapper.ts) already build for their own
 * imports. Excel import used to create only nodes, no connections at all.
 *
 * Returns from/to id pairs only, no `id`/other VsmConnection metadata — the
 * caller mints those (same as it already does for the nodes themselves via
 * crypto.randomUUID()), keeping this function pure/deterministic and easy
 * to unit-test.
 */
export function buildLinearConnectionPairs(nodeIds: string[]): Array<Pick<VsmConnection, 'fromNodeId' | 'toNodeId'>> {
  const pairs: Array<Pick<VsmConnection, 'fromNodeId' | 'toNodeId'>> = []
  for (let i = 0; i < nodeIds.length - 1; i++) {
    pairs.push({ fromNodeId: nodeIds[i], toNodeId: nodeIds[i + 1] })
  }
  return pairs
}
