import { describe, it, expect, vi } from 'vitest';
import { CommandBus } from '@application/handlers/CommandBus';
import { QueryBus } from '@application/handlers/QueryBus';
import { EventBus } from '@domain/events/EventBus';
import type { AppState, StateRepository } from '@domain/ports/StateRepository';
import { createStartTimerHandler } from '@application/commands/StartTimer';
import { createStopTimerHandler } from '@application/commands/StopTimer';
import { createCreateEnclosHandler } from '@application/commands/CreateEnclos';
import { createAddDragodindeHandler } from '@application/commands/AddDragodinde';
import { createToggleGaugeHandler } from '@application/commands/UpdateGauge';
import { createGetTimerStateHandler } from '@application/queries/GetTimerState';
import { createGetDashboardHandler } from '@application/queries/GetDashboard';

function setup() {
  const repo: StateRepository = { load: vi.fn(async () => null), save: vi.fn() };
  const events = new EventBus();
  const state: AppState = {
    enclos: [], activeId: 'dashboard', nextEnclosId: 1,
    alarmSound: 'arpege', notifsEnabled: true, ntfyTopic: '',
    archivedStats: [], inventaire: {}, workflows: [], accouplements: [],
  };

  const cmdBus = new CommandBus();
  const qBus = new QueryBus();

  cmdBus.register('create-enclos', createCreateEnclosHandler(state, repo));
  cmdBus.register('add-dragodinde', createAddDragodindeHandler(state, repo));
  cmdBus.register('toggle-gauge', createToggleGaugeHandler(state, repo));
  cmdBus.register('start-timer', createStartTimerHandler(state, repo));
  cmdBus.register('stop-timer', createStopTimerHandler(state, repo));

  qBus.register('get-timer-state', createGetTimerStateHandler(state));
  qBus.register('get-dashboard', createGetDashboardHandler(state));

  return { state, repo, events, cmdBus, qBus };
}

describe('Timer Workflow', () => {
  it('full lifecycle: create → configure → start → stop', () => {
    const { state, cmdBus, qBus } = setup();

    // 1. Create enclos (starts with 1 DD automatically)
    cmdBus.execute({ type: 'create-enclos' });
    expect(state.enclos).toHaveLength(1);
    expect(state.enclos[0]!.dragodindes).toHaveLength(1);

    const encId = state.enclos[0]!.id;

    // 2. Toggle gauge
    cmdBus.execute({ type: 'toggle-gauge', enclosId: encId, gaugeId: 'baffeur' });
    expect(state.enclos[0]!.activeGauges).toContain('baffeur');

    // 3. Set gauge level (modify state directly since we don't have that command wired)
    state.enclos[0]!.gaugeLevels.baffeur = 50000;

    // 4. Start timer
    cmdBus.execute({ type: 'start-timer', enclosId: encId });
    const timerState = qBus.execute<any>({ type: 'get-timer-state', enclosId: encId });
    expect(timerState.running).toBe(true);

    // 5. Stop timer
    cmdBus.execute({ type: 'stop-timer', enclosId: encId });
    const stopped = qBus.execute<any>({ type: 'get-timer-state', enclosId: encId });
    expect(stopped.running).toBe(false);
  });

  it('dashboard reflects enclos state', () => {
    const { cmdBus, qBus } = setup();

    cmdBus.execute({ type: 'create-enclos' });
    cmdBus.execute({ type: 'create-enclos' });

    const dash = qBus.execute<any>({ type: 'get-dashboard' });
    expect(dash.enclosSummaries).toHaveLength(2);
  });
});
