import { describe, it, expect } from 'vitest'
import {
  normalizeImportRow,
  buildProcessExportRows,
  buildOverwriteInserts,
  type ParsedImportRow,
} from '@/lib/stopwatch/excel-import'

describe('normalizeImportRow', () => {
  it('parses a canonical template row', () => {
    const row = normalizeImportRow({
      Station: 'Assembly-1',
      'Cycle #': 2,
      'CT (seconds)': 12.34,
      Notes: 'ok',
    })
    expect(row).toEqual({
      stationName: 'Assembly-1',
      cycleNum: 2,
      ct: 12.34,
      notes: 'ok',
    })
  })

  it('accepts flexible column names (CT / ct / cycle_time_sec, Cycle)', () => {
    expect(normalizeImportRow({ ct: '5', Cycle: '3' })).toMatchObject({
      ct: 5,
      cycleNum: 3,
    })
    expect(normalizeImportRow({ cycle_time_sec: 7.5 })).toMatchObject({ ct: 7.5 })
  })

  it('treats a German decimal comma as a decimal point', () => {
    expect(normalizeImportRow({ 'CT (seconds)': '1,90' })?.ct).toBe(1.9)
  })

  it('rounds the cycle time to two decimals', () => {
    expect(normalizeImportRow({ 'CT (seconds)': 5.678 })?.ct).toBe(5.68)
  })

  it('returns null for non-numeric or non-positive cycle times', () => {
    expect(normalizeImportRow({ 'CT (seconds)': '' })).toBeNull()
    expect(normalizeImportRow({ 'CT (seconds)': 'abc' })).toBeNull()
    expect(normalizeImportRow({ 'CT (seconds)': 0 })).toBeNull()
    expect(normalizeImportRow({ 'CT (seconds)': -3 })).toBeNull()
    expect(normalizeImportRow({ Station: 'X' })).toBeNull()
  })

  it('defaults cycleNum to 0 and notes to null when absent', () => {
    const row = normalizeImportRow({ 'CT (seconds)': 4 })
    expect(row).toEqual({ stationName: '', cycleNum: 0, ct: 4, notes: null })
  })

  it('trims the station name', () => {
    expect(normalizeImportRow({ Station: '  Linie 1  ', CT: 2 })?.stationName).toBe(
      'Linie 1'
    )
  })

  it('coerces a numeric note to string', () => {
    expect(normalizeImportRow({ CT: 2, Notes: 42 })?.notes).toBe('42')
  })
})

describe('buildProcessExportRows', () => {
  it('exports one row per measurement in cycle order, renumbered #1..n', () => {
    const rows = buildProcessExportRows('Assembly-1', [
      { cycle_number: 3, cycle_time_sec: 12, notes: 'c' },
      { cycle_number: 1, cycle_time_sec: 10, notes: null },
      { cycle_number: 2, cycle_time_sec: 11, notes: 'b' },
    ])
    expect(rows).toEqual([
      { station: 'Assembly-1', cycle: 1, ct: 10, notes: null },
      { station: 'Assembly-1', cycle: 2, ct: 11, notes: 'b' },
      { station: 'Assembly-1', cycle: 3, ct: 12, notes: 'c' },
    ])
  })

  it('normalises a missing note to null', () => {
    const rows = buildProcessExportRows('S', [{ cycle_number: 1, cycle_time_sec: 5 }])
    expect(rows[0].notes).toBeNull()
  })

  it('returns an empty array when there are no measurements', () => {
    expect(buildProcessExportRows('S', [])).toEqual([])
  })
})

describe('buildOverwriteInserts', () => {
  const parsed = (ct: number, notes: string | null = null): ParsedImportRow => ({
    stationName: 'ignored',
    cycleNum: 0,
    ct,
    notes,
  })

  it('maps parsed rows to inserts for one process, renumbered #1..n', () => {
    const inserts = buildOverwriteInserts('step-1', [parsed(10, 'a'), parsed(20), parsed(30)])
    expect(inserts).toEqual([
      { process_step_id: 'step-1', cycle_number: 1, cycle_time_sec: 10, notes: 'a' },
      { process_step_id: 'step-1', cycle_number: 2, cycle_time_sec: 20, notes: null },
      { process_step_id: 'step-1', cycle_number: 3, cycle_time_sec: 30, notes: null },
    ])
  })

  it('returns an empty array for no rows (overwrite with nothing = clear)', () => {
    expect(buildOverwriteInserts('step-1', [])).toEqual([])
  })
})
