import { describe, it, expect, beforeEach } from 'vitest'
import {
  loadDraft,
  saveDraft,
  clearDraft,
  type DraftStorage,
  type WorkshopDraft,
} from '../workshop-draft'

function makeStorage(): DraftStorage {
  const map = new Map<string, string>()
  return {
    getItem: (k) => map.get(k) ?? null,
    setItem: (k, v) => { map.set(k, v) },
    removeItem: (k) => { map.delete(k) },
  }
}

function makeDraft(overrides: Partial<WorkshopDraft> = {}): WorkshopDraft {
  return {
    projectId: 'proj-123',
    savedAt: '2026-06-07T10:00:00.000Z',
    observations: {
      'step-1': {
        observed_ct_sec: 45,
        machine_time_sec: 20,
        value_add_time_sec: 15,
        non_va_time_sec: 5,
        load_unload_time_sec: 5,
        waiting_time_sec: null,
        output_per_shift: 480,
        scrap_count: 2,
        actual_oee: 0.85,
        comment: 'Testkommentar',
      },
    },
    optimizations: {
      'step-1': {
        possible_ct_sec: 38,
        machine_time_sec: 18,
        value_add_time_sec: 12,
        non_va_time_sec: 4,
        load_unload_time_sec: 4,
        waiting_time_sec: null,
        comment: null,
      },
    },
    ...overrides,
  }
}

describe('workshop-draft store', () => {
  let storage: DraftStorage

  beforeEach(() => {
    storage = makeStorage()
  })

  it('returns null when no draft is stored', () => {
    expect(loadDraft('proj-123', storage)).toBeNull()
  })

  it('persists a draft and loads it back for the correct project', () => {
    const draft = makeDraft()
    saveDraft(draft, storage)
    const loaded = loadDraft('proj-123', storage)
    expect(loaded).not.toBeNull()
    expect(loaded?.projectId).toBe('proj-123')
    expect(loaded?.observations['step-1']?.observed_ct_sec).toBe(45)
  })

  it('returns null for a different projectId', () => {
    saveDraft(makeDraft({ projectId: 'proj-A' }), storage)
    expect(loadDraft('proj-B', storage)).toBeNull()
  })

  it('does not leak between projects (separate keys)', () => {
    saveDraft(makeDraft({ projectId: 'proj-A' }), storage)
    saveDraft(makeDraft({ projectId: 'proj-B', savedAt: '2026-06-07T11:00:00.000Z' }), storage)
    const a = loadDraft('proj-A', storage)
    const b = loadDraft('proj-B', storage)
    expect(a?.savedAt).toBe('2026-06-07T10:00:00.000Z')
    expect(b?.savedAt).toBe('2026-06-07T11:00:00.000Z')
  })

  it('clears a draft after successful server save', () => {
    saveDraft(makeDraft(), storage)
    clearDraft('proj-123', storage)
    expect(loadDraft('proj-123', storage)).toBeNull()
  })

  it('survives corrupt JSON without throwing', () => {
    storage.setItem('kadi:workshop-draft:v1:proj-123', '{not valid json')
    expect(loadDraft('proj-123', storage)).toBeNull()
  })

  it('is a no-op when storage is null', () => {
    expect(() => saveDraft(makeDraft(), null)).not.toThrow()
    expect(loadDraft('proj-123', null)).toBeNull()
    expect(() => clearDraft('proj-123', null)).not.toThrow()
  })

  it('overwrites an older draft on subsequent saves', () => {
    saveDraft(makeDraft({ savedAt: '2026-06-07T10:00:00.000Z' }), storage)
    saveDraft(
      makeDraft({
        savedAt: '2026-06-07T10:30:00.000Z',
        observations: { 'step-1': { ...makeDraft().observations['step-1']!, observed_ct_sec: 99 } },
      }),
      storage,
    )
    const loaded = loadDraft('proj-123', storage)
    expect(loaded?.savedAt).toBe('2026-06-07T10:30:00.000Z')
    expect(loaded?.observations['step-1']?.observed_ct_sec).toBe(99)
  })
})
