/**
 * ProjectCreationWizard — Unit tests for wizard state management
 *
 * Tests the step-sequencing logic and validation rules defined in WizardContext.
 * These are pure logic tests — no DOM or React renderer required.
 *
 * The functions below mirror the private helpers in WizardContext.tsx.
 * If the context logic changes, update both files.
 */

import { describe, it, expect } from '@jest/globals';

// ---- Step sequencing (mirrors WizardContext.getStepSequence) ---------------

function getStepSequence(mode) {
  switch (mode) {
    case 'quick':
      return ['basics'];
    case 'guided':
      return ['basics', 'preset', 'review'];
    case 'ai':
      return ['basics', 'preset', 'review'];
    default:
      return ['basics'];
  }
}

// ---- Validation (mirrors WizardContext.isStepValid) ------------------------

function isStepValid(step, state) {
  switch (step) {
    case 'entry':
      return true;
    case 'basics':
      return state.projectName.trim().length > 0 && state.location.length > 0;
    case 'preset':
      return state.selectedPresetId.length > 0;
    case 'review':
      return true;
    default:
      return false;
  }
}

// ---- Step navigation (mirrors WizardContext goNext/goBack logic) -----------

function goNext(state) {
  if (state.currentStep === 'entry') {
    const seq = getStepSequence(state.mode);
    return seq[0];
  }
  const seq = getStepSequence(state.mode);
  const idx = seq.indexOf(state.currentStep);
  if (idx === -1 || idx >= seq.length - 1) return state.currentStep;
  return seq[idx + 1];
}

function goBack(state) {
  if (state.currentStep === 'entry') return 'entry';
  const seq = getStepSequence(state.mode);
  const idx = seq.indexOf(state.currentStep);
  if (idx <= 0) return 'entry';
  return seq[idx - 1];
}

// ---- Whether the current step is the last one before creation --------------

function isLastStep(mode, step) {
  return step === 'review' || (mode === 'quick' && step === 'basics');
}

// ============================================================================
// Tests
// ============================================================================

describe('WizardContext: step sequences', () => {
  it('quick mode only visits basics', () => {
    expect(getStepSequence('quick')).toEqual(['basics']);
  });

  it('guided mode visits basics, preset, review', () => {
    expect(getStepSequence('guided')).toEqual(['basics', 'preset', 'review']);
  });

  it('ai mode uses same sequence as guided (V1 stub)', () => {
    expect(getStepSequence('ai')).toEqual(['basics', 'preset', 'review']);
  });
});

describe('WizardContext: validation', () => {
  const baseState = {
    mode: 'quick',
    currentStep: 'basics',
    projectName: '',
    description: '',
    location: '',
    selectedPresetId: 'modern'
  };

  it('entry step is always valid', () => {
    expect(isStepValid('entry', { ...baseState, currentStep: 'entry' })).toBe(true);
  });

  it('review step is always valid', () => {
    expect(isStepValid('review', { ...baseState, currentStep: 'review' })).toBe(true);
  });

  it('basics step requires projectName and location', () => {
    expect(isStepValid('basics', baseState)).toBe(false);
  });

  it('basics step passes with name and location', () => {
    expect(isStepValid('basics', { ...baseState, projectName: 'My Project', location: '/tmp' })).toBe(true);
  });

  it('basics step trims whitespace on projectName', () => {
    expect(isStepValid('basics', { ...baseState, projectName: '   ', location: '/tmp' })).toBe(false);
  });

  it('preset step requires selectedPresetId', () => {
    expect(isStepValid('preset', { ...baseState, selectedPresetId: '' })).toBe(false);
  });

  it('preset step passes with a preset id', () => {
    expect(isStepValid('preset', { ...baseState, selectedPresetId: 'minimal' })).toBe(true);
  });
});

describe('WizardContext: goNext navigation', () => {
  const baseState = {
    mode: 'quick',
    currentStep: 'entry',
    projectName: 'Test',
    description: '',
    location: '/tmp',
    selectedPresetId: 'modern'
  };

  it('quick: entry advances to basics', () => {
    expect(goNext({ ...baseState, mode: 'quick', currentStep: 'entry' })).toBe('basics');
  });

  it('quick: basics stays (is the last step)', () => {
    expect(goNext({ ...baseState, mode: 'quick', currentStep: 'basics' })).toBe('basics');
  });

  it('guided: entry advances to basics', () => {
    expect(goNext({ ...baseState, mode: 'guided', currentStep: 'entry' })).toBe('basics');
  });

  it('guided: basics advances to preset', () => {
    expect(goNext({ ...baseState, mode: 'guided', currentStep: 'basics' })).toBe('preset');
  });

  it('guided: preset advances to review', () => {
    expect(goNext({ ...baseState, mode: 'guided', currentStep: 'preset' })).toBe('review');
  });

  it('guided: review stays (is the last step)', () => {
    expect(goNext({ ...baseState, mode: 'guided', currentStep: 'review' })).toBe('review');
  });
});

describe('WizardContext: goBack navigation', () => {
  const baseState = {
    mode: 'guided',
    currentStep: 'review',
    projectName: 'Test',
    description: '',
    location: '/tmp',
    selectedPresetId: 'modern'
  };

  it('entry stays on entry when going back', () => {
    expect(goBack({ ...baseState, currentStep: 'entry' })).toBe('entry');
  });

  it('guided: basics goes back to entry', () => {
    expect(goBack({ ...baseState, currentStep: 'basics' })).toBe('entry');
  });

  it('guided: preset goes back to basics', () => {
    expect(goBack({ ...baseState, currentStep: 'preset' })).toBe('basics');
  });

  it('guided: review goes back to preset', () => {
    expect(goBack({ ...baseState, currentStep: 'review' })).toBe('preset');
  });

  it('quick: basics goes back to entry', () => {
    expect(goBack({ ...baseState, mode: 'quick', currentStep: 'basics' })).toBe('entry');
  });
});

describe('isLastStep: determines when to show Create Project button', () => {
  it('quick mode: basics is the last step', () => {
    expect(isLastStep('quick', 'basics')).toBe(true);
  });

  it('quick mode: entry is not the last step', () => {
    expect(isLastStep('quick', 'entry')).toBe(false);
  });

  it('guided mode: review is the last step', () => {
    expect(isLastStep('guided', 'review')).toBe(true);
  });

  it('guided mode: basics is not the last step', () => {
    expect(isLastStep('guided', 'basics')).toBe(false);
  });

  it('guided mode: preset is not the last step', () => {
    expect(isLastStep('guided', 'preset')).toBe(false);
  });
});
