// Verlagerte Untervorgänge und die Zeitgutschrift-Frage (Kap. 7.4, R-10).

import { describe, it, expect } from 'vitest'
import { diffSubOperations, timeCreditQuestion, type SubOperation } from '../manufacturing-sub-operations'

const op = (row: number, name: string): SubOperation => ({ row, name })

describe('diffSubOperations', () => {
  it('erkennt unveränderte Untervorgänge', () => {
    const d = diffSubOperations([op(1, 'Bauteil einlegen')], [op(1, 'Bauteil einlegen')])
    expect(d.counts).toMatchObject({ removed: 0, added: 0, renamed: 0 })
  })

  it('erkennt einen weggefallenen Arbeitsschritt', () => {
    const d = diffSubOperations([op(1, 'Bauteil einlegen'), op(2, 'Zwei Schrauben anziehen')], [op(1, 'Bauteil einlegen')])
    expect(d.removed.map((o) => o.name)).toEqual(['Zwei Schrauben anziehen'])
    expect(d.added).toEqual([])
  })

  it('paart mehrfach vorkommende Schritte über die erhaltene Reihenfolge', () => {
    // „Zwei Schrauben anziehen" steht an vielen Stellen — nur die Reihenfolge
    // sagt, welches welches ist. Dieselbe Logik wie bei den Gleichteilen der
    // Stückliste.
    const d = diffSubOperations(
      [op(1, 'Schrauben anziehen'), op(5, 'Schrauben anziehen'), op(9, 'Schrauben anziehen')],
      [op(2, 'Schrauben anziehen'), op(6, 'Schrauben anziehen')],
    )
    expect(d.counts.removed).toBe(1)
    expect(d.counts.added).toBe(0)
  })

  it('zählt eine reine Umbenennung nicht als Wegfall plus Zuwachs', () => {
    const d = diffSubOperations(
      [op(1, 'Bauteil einlegen'), op(2, 'Vehicle Bracket auf Vorrichtung legen')],
      [op(1, 'Bauteil einlegen'), op(2, 'Auf Vorrichtung legen')],
    )
    expect(d.counts.renamed).toBe(1)
    expect(d.counts.removed).toBe(0)
    expect(d.counts.added).toBe(0)
    expect(d.renamed[0].award.name).toBe('Vehicle Bracket auf Vorrichtung legen')
  })

  it('lässt einen echten Wegfall stehen, wenn nichts zum Paaren da ist', () => {
    const d = diffSubOperations([op(1, 'A'), op(2, 'B'), op(3, 'C')], [op(1, 'A')])
    expect(d.counts.removed).toBe(2)
    expect(d.counts.renamed).toBe(0)
  })

  it('übergeht namenlose Zeilen', () => {
    const d = diffSubOperations([op(1, '  '), op(2, 'A')], [op(1, 'A')])
    expect(d.counts.removed).toBe(0)
    expect(d.counts.added).toBe(0)
  })

  it('zählt beide Seiten vollständig', () => {
    const d = diffSubOperations([op(1, 'A'), op(2, 'B')], [op(1, 'A'), op(2, 'C'), op(3, 'D')])
    expect(d.counts.award).toBe(2)
    expect(d.counts.current).toBe(3)
  })
})

describe('timeCreditQuestion', () => {
  const mitWegfall = diffSubOperations([op(1, 'A'), op(2, 'B')], [op(1, 'A')])
  const ohneWegfall = diffSubOperations([op(1, 'A')], [op(1, 'A')])

  it('stellt die Frage, wenn Schritte wegfallen und die Taktzeiten stehen bleiben', () => {
    const q = timeCreditQuestion(mitWegfall, true)
    expect(q.raised).toBe(true)
    expect(q.removedCount).toBe(1)
    expect(q.questionDe).toContain('Wo ist die Zeit verrechnet')
  })

  it('stellt sie nicht, wenn sich die Taktzeiten geändert haben', () => {
    // Dann ist die Zeit sichtbar verrechnet — es gibt nichts zu fragen.
    expect(timeCreditQuestion(mitWegfall, false).raised).toBe(false)
  })

  it('stellt sie nicht ohne Wegfall', () => {
    expect(timeCreditQuestion(ohneWegfall, true).raised).toBe(false)
    expect(timeCreditQuestion(ohneWegfall, true).questionDe).toBeNull()
  })
})
