import { describe, it, expect, vi, beforeEach } from 'vitest';
import { LocalStorageRepository } from '@infrastructure/persistence/LocalStorageRepository';

// Mock localStorage
const store: Record<string, string> = {};
const mockLocalStorage = {
  getItem: vi.fn((key: string) => store[key] ?? null),
  setItem: vi.fn((key: string, val: string) => { store[key] = val; }),
  removeItem: vi.fn((key: string) => { delete store[key]; }),
};

beforeEach(() => {
  Object.keys(store).forEach(k => delete store[k]);
  vi.stubGlobal('localStorage', mockLocalStorage);
  // No electronAPI in test
  if (typeof window !== 'undefined') {
    delete (window as any).electronAPI;
  }
});

describe('LocalStorageRepository', () => {
  it('load returns null if no stored data', async () => {
    const repo = new LocalStorageRepository();
    const result = await repo.load();
    expect(result).toBeNull();
  });

  it('save then load round-trips', async () => {
    const repo = new LocalStorageRepository();
    const state = {
      enclos: [], activeId: null, nextEnclosId: 1,
      alarmSound: 'arpege', notifsEnabled: true, ntfyTopic: '',
      archivedStats: [], inventaire: {}, workflows: [], accouplements: [],
    };
    repo.save(state as any);
    const loaded = await repo.load();
    expect(loaded).not.toBeNull();
    expect(loaded!.alarmSound).toBe('arpege');
    expect(loaded!.accouplements).toEqual([]);
  });

  it('save resets timer running state', async () => {
    const repo = new LocalStorageRepository();
    const state = {
      enclos: [{
        id: 1, name: 'E1', activeGauges: [], gaugeLevels: { baffeur: 0, caresseur: 0, foudroyeur: 0, abreuvoir: 0, dragofesse: 0, mangeoire: 0 },
        dragodindes: [], nextDdId: 1,
        timer: { running: true, startTime: Date.now(), pausedAt: null, pausedMs: 0, snapGauges: {}, snapStats: {} },
        alerted: {},
      }],
      activeId: 1, nextEnclosId: 2,
      alarmSound: 'arpege', notifsEnabled: true, ntfyTopic: '',
      archivedStats: [], inventaire: {}, workflows: [], accouplements: [],
    };
    repo.save(state as any);
    const loaded = await repo.load();
    expect(loaded!.enclos[0]!.timer.running).toBe(false);
  });

  it('deserialize applies default targets migration', async () => {
    const repo = new LocalStorageRepository();
    const raw = JSON.stringify({
      enclos: [{
        id: 1, name: 'E1', activeGauges: [], gaugeLevels: { baffeur: 0, caresseur: 0, foudroyeur: 0, abreuvoir: 0, dragofesse: 0, mangeoire: 0 },
        dragodindes: [{ id: 1, name: 'DD1', stats: { serenite: 0, endurance: 0, maturite: 0, amour: 0 }, targets: {}, race: '', gender: 'n', reproducteur: 0 }],
        nextDdId: 2,
        timer: { running: false, startTime: null, pausedAt: null, pausedMs: 0, snapGauges: {}, snapStats: {} },
        alerted: {},
      }],
      activeId: 1, nextEnclosId: 2, alarmSound: 'arpege', notifsEnabled: true,
    });
    store['dd3v3'] = raw;
    const loaded = await repo.load();
    expect(loaded!.enclos[0]!.dragodindes[0]!.targets.baffeur).toBe(-5000);
    expect(loaded!.enclos[0]!.dragodindes[0]!.stats.xp).toBe(1);
  });
});
