/**
 * Tests for useWizardState hook
 */

import { renderHook, act } from '@testing-library/react';
import { useWizardState } from '@/components/projects/wizard/useWizardState';
import { WIZARD_STEPS } from '@/components/projects/wizard/constants';

describe('useWizardState', () => {
  describe('initial state', () => {
    it('starts at step 1', () => {
      const { result } = renderHook(() => useWizardState());
      expect(result.current.state.step).toBe(1);
    });

    it('has empty form fields', () => {
      const { result } = renderHook(() => useWizardState());
      expect(result.current.state.projectName).toBe('');
      expect(result.current.state.description).toBe('');
      expect(result.current.state.repoUrl).toBe('');
    });

    it('has null selections', () => {
      const { result } = renderHook(() => useWizardState());
      expect(result.current.state.complexity).toBeNull();
      expect(result.current.state.clientMode).toBeNull();
      expect(result.current.state.autonomyLevel).toBeNull();
    });

    it('is not in script mode', () => {
      const { result } = renderHook(() => useWizardState());
      expect(result.current.isScriptMode).toBe(false);
    });
  });

  describe('updateState', () => {
    it('updates project name', () => {
      const { result } = renderHook(() => useWizardState());
      act(() => {
        result.current.updateState({ projectName: 'Test Project' });
      });
      expect(result.current.state.projectName).toBe('Test Project');
    });

    it('updates multiple fields at once', () => {
      const { result } = renderHook(() => useWizardState());
      act(() => {
        result.current.updateState({
          projectName: 'Test',
          description: 'A test project',
        });
      });
      expect(result.current.state.projectName).toBe('Test');
      expect(result.current.state.description).toBe('A test project');
    });
  });

  describe('resetState', () => {
    it('resets to initial state', () => {
      const { result } = renderHook(() => useWizardState());

      // Make some changes
      act(() => {
        result.current.updateState({
          projectName: 'Test',
          complexity: 'medium',
          step: 3,
        });
      });

      // Reset
      act(() => {
        result.current.resetState();
      });

      expect(result.current.state.projectName).toBe('');
      expect(result.current.state.complexity).toBeNull();
      expect(result.current.state.step).toBe(1);
    });
  });

  describe('canProceed', () => {
    it('requires project name at least 3 chars for step 1', () => {
      const { result } = renderHook(() => useWizardState());

      expect(result.current.canProceed).toBe(false);

      act(() => {
        result.current.updateState({ projectName: 'AB' });
      });
      expect(result.current.canProceed).toBe(false);

      act(() => {
        result.current.updateState({ projectName: 'ABC' });
      });
      expect(result.current.canProceed).toBe(true);
    });

    it('requires complexity selection for step 2', () => {
      const { result } = renderHook(() => useWizardState());

      // Move to step 2
      act(() => {
        result.current.updateState({ projectName: 'Test', step: 2 });
      });

      expect(result.current.canProceed).toBe(false);

      act(() => {
        result.current.updateState({ complexity: 'medium' });
      });
      expect(result.current.canProceed).toBe(true);
    });

    it('requires client mode selection for step 3 (non-script)', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'Test',
          complexity: 'medium',
          step: 3,
        });
      });

      expect(result.current.canProceed).toBe(false);

      act(() => {
        result.current.updateState({ clientMode: 'technical' });
      });
      expect(result.current.canProceed).toBe(true);
    });

    it('requires autonomy level for step 4 (non-script)', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'Test',
          complexity: 'medium',
          clientMode: 'auto',
          step: 4,
        });
      });

      expect(result.current.canProceed).toBe(false);

      act(() => {
        result.current.updateState({ autonomyLevel: 'milestone' });
      });
      expect(result.current.canProceed).toBe(true);
    });

    it('always allows proceeding from step 5 (agent chat)', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({ step: 5 });
      });

      expect(result.current.canProceed).toBe(true);
    });
  });

  describe('navigation', () => {
    it('goNext increments step', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({ projectName: 'Test Project' });
      });

      act(() => {
        result.current.goNext();
      });

      expect(result.current.state.step).toBe(2);
    });

    it('goBack decrements step', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({ projectName: 'Test', step: 3 });
      });

      act(() => {
        result.current.goBack();
      });

      expect(result.current.state.step).toBe(2);
    });

    it('goBack does nothing at step 1', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.goBack();
      });

      expect(result.current.state.step).toBe(1);
    });

    it('does not proceed when canProceed is false', () => {
      const { result } = renderHook(() => useWizardState());

      // Project name too short
      act(() => {
        result.current.updateState({ projectName: 'AB' });
      });

      act(() => {
        result.current.goNext();
      });

      expect(result.current.state.step).toBe(1);
    });
  });

  describe('script mode', () => {
    it('sets isScriptMode when complexity is script', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({ complexity: 'script' });
      });

      expect(result.current.isScriptMode).toBe(true);
    });

    it('skips from step 2 to step 5 for scripts', () => {
      const { result } = renderHook(() => useWizardState());

      // Set up step 2 with script complexity
      act(() => {
        result.current.updateState({
          projectName: 'Test Script',
          step: 2,
          complexity: 'script',
        });
      });

      // Go next should skip to step 5
      act(() => {
        result.current.goNext();
      });

      expect(result.current.state.step).toBe(WIZARD_STEPS.AGENT_CHAT);
    });

    it('auto-sets clientMode and autonomyLevel for scripts', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'Test Script',
          step: 2,
          complexity: 'script',
        });
      });

      act(() => {
        result.current.goNext();
      });

      expect(result.current.state.clientMode).toBe('auto');
      expect(result.current.state.autonomyLevel).toBe('autonomous');
    });

    it('goBack from step 5 goes to step 2 for scripts', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'Test Script',
          complexity: 'script',
          step: 5,
        });
      });

      act(() => {
        result.current.goBack();
      });

      expect(result.current.state.step).toBe(WIZARD_STEPS.COMPLEXITY);
    });
  });

  describe('getProjectData', () => {
    it('generates correct project data', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'My Test Project',
          description: 'A description',
          repoUrl: 'https://github.com/test/repo',
          complexity: 'medium',
          clientMode: 'technical',
          autonomyLevel: 'milestone',
        });
      });

      const data = result.current.getProjectData();

      expect(data.name).toBe('My Test Project');
      expect(data.slug).toBe('my-test-project');
      expect(data.description).toBe('A description');
      expect(data.autonomy_level).toBe('milestone');
      expect(data.settings.complexity).toBe('medium');
      expect(data.settings.client_mode).toBe('technical');
      expect(data.settings.repo_url).toBe('https://github.com/test/repo');
    });

    it('generates URL-safe slug', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'My Project! With Special @#$ Characters',
        });
      });

      const data = result.current.getProjectData();
      expect(data.slug).toBe('my-project-with-special-characters');
    });

    it('excludes empty repoUrl from settings', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'Test Project',
          repoUrl: '',
        });
      });

      const data = result.current.getProjectData();
      expect(data.settings.repo_url).toBeUndefined();
    });

    it('uses defaults for null values', () => {
      const { result } = renderHook(() => useWizardState());

      act(() => {
        result.current.updateState({
          projectName: 'Test Project',
        });
      });

      const data = result.current.getProjectData();
      expect(data.autonomy_level).toBe('milestone');
      expect(data.settings.complexity).toBe('medium');
      expect(data.settings.client_mode).toBe('auto');
    });
  });
});
