import { describe, it, expect, beforeEach, vi } from 'vitest';
import { RoadmapWizard } from '../roadmap-wizard.js';
import { RoadmapManager } from '../roadmap-manager.js';
import { PrioritizationEngine } from '../prioritization-engine.js';
import { ConfigManager } from '../../../config/config-manager.js';

// Mock the dependencies
vi.mock('../roadmap-manager.js');
vi.mock('../prioritization-engine.js');

describe('RoadmapWizard', () => {
  let wizard: RoadmapWizard;
  let mockRoadmapManager: any;
  let mockPrioritizationEngine: any;
  const sessionId = 'test-session-123';

  beforeEach(() => {
    // Create mock instances
    mockRoadmapManager = {
      createRoadmap: vi.fn().mockResolvedValue({
        id: 'roadmap-123',
        name: 'Test Roadmap',
        vision: 'Test Vision',
        timeHorizon: 'annual',
        owner: 'Test Owner',
        stakeholders: [],
        status: 'draft',
        themes: [],
        milestones: [],
        releases: [],
        createdAt: new Date(),
        updatedAt: new Date(),
        metrics: {
          featuresPlanned: 0,
          featuresCompleted: 0,
          initiativesActive: 0,
          velocityTrend: 'stable',
          onTimeDelivery: 100,
          valueDelivered: 0
        }
      }),
      addTheme: vi.fn().mockResolvedValue({
        id: 'theme-123',
        name: 'Test Theme',
        description: 'Test Description',
        objectives: ['Objective 1'],
        priority: 'must-have',
        timeframe: {
          startQuarter: 'Q1 2024',
          endQuarter: 'Q4 2024'
        },
        status: 'planned',
        initiatives: [],
        metrics: {
          initiativesTotal: 0,
          initiativesCompleted: 0,
          featuresTotal: 0,
          featuresCompleted: 0,
          progressPercentage: 0,
          valueScore: 0
        }
      }),
      createInitiative: vi.fn().mockImplementation((options) => Promise.resolve({
        id: 'init-123',
        themeId: options.themeId,
        title: options.title,
        description: options.description,
        features: [],
        epicIds: [],
        value: options.estimatedValue,
        effort: options.estimatedEffort,
        risks: options.risks || [],
        dependencies: [],
        status: 'ideation'
      })),
      addFeature: vi.fn().mockImplementation((options) => Promise.resolve({
        id: 'feature-123',
        initiativeId: options.initiativeId,
        name: options.name,
        description: options.description,
        userStories: [],
        priority: 0,
        businessValue: options.businessValue,
        technicalComplexity: options.technicalComplexity,
        status: 'proposed'
      })),
      getRoadmap: vi.fn().mockResolvedValue({
        id: 'roadmap-123',
        name: 'Test Roadmap',
        themes: []
      }),
      getThemeDetails: vi.fn().mockResolvedValue({
        theme: {
          id: 'theme-123',
          name: 'Test Theme'
        },
        initiatives: [],
        features: []
      })
    };

    mockPrioritizationEngine = {};

    wizard = new RoadmapWizard(mockRoadmapManager, mockPrioritizationEngine);
  });

  describe('Roadmap Wizard', () => {
    it('should start roadmap wizard and return step 1 instructions', async () => {
      const result = await wizard.startRoadmapWizard(sessionId);

      expect(result).toContain('Product Roadmap Creation Wizard');
      expect(result).toContain('Step 1/4: Basic Information');
      expect(result).toContain('Product/Roadmap Name');
      expect(result).toContain('Vision Statement');
      expect(result).toContain('Time Horizon');
      expect(result).toContain('Your Name/Role');
    });

    it('should progress through wizard steps', async () => {
      // Start wizard
      await wizard.startRoadmapWizard(sessionId);

      // Step 1 -> Step 2
      const step2Result = await wizard.continueRoadmapWizard(sessionId, {
        name: 'My Product',
        vision: 'Amazing product vision',
        timeHorizon: 'annual',
        owner: 'John Doe'
      });

      expect(step2Result).toContain('Step 2/4: Key Stakeholders');
      expect(step2Result).toContain('stakeholders');

      // Step 2 -> Step 3
      const step3Result = await wizard.continueRoadmapWizard(sessionId, {
        stakeholders: ['Jane Smith', 'Bob Johnson']
      });

      expect(step3Result).toContain('Step 3/4: Strategic Context');
      expect(step3Result).toContain('Primary Goal');
      expect(step3Result).toContain('Key Challenges');

      // Step 3 -> Step 4
      const step4Result = await wizard.continueRoadmapWizard(sessionId, {
        goal: 'Customer satisfaction',
        challenges: ['High support volume', 'Poor UX'],
        metrics: ['NPS > 50', 'Support tickets -50%']
      });

      expect(step4Result).toContain('Step 4/4: Initial Themes');
      expect(step4Result).toContain('strategic themes');
    });

    it('should complete wizard and create roadmap', async () => {
      // Progress through all steps
      await wizard.startRoadmapWizard(sessionId);
      
      await wizard.continueRoadmapWizard(sessionId, {
        name: 'My Product',
        vision: 'Amazing product vision',
        timeHorizon: 'annual',
        owner: 'John Doe'
      });

      await wizard.continueRoadmapWizard(sessionId, {
        stakeholders: ['Jane Smith']
      });

      await wizard.continueRoadmapWizard(sessionId, {
        goal: 'Customer satisfaction',
        challenges: ['High support volume'],
        metrics: ['NPS > 50']
      });

      // Complete wizard with themes
      const result = await wizard.continueRoadmapWizard(sessionId, {
        themes: [
          {
            name: 'Self-Service',
            description: 'Build self-service capabilities',
            priority: 'must-have',
            startQuarter: 'Q1 2024',
            endQuarter: 'Q4 2024'
          }
        ]
      });

      expect(result).toContain('Roadmap Created Successfully!');
      expect(result).toContain('roadmap-123');
      expect(mockRoadmapManager.createRoadmap).toHaveBeenCalledWith({
        name: 'My Product',
        vision: 'Amazing product vision',
        timeHorizon: 'annual',
        owner: 'John Doe',
        stakeholders: ['Jane Smith']
      });
      expect(mockRoadmapManager.addTheme).toHaveBeenCalled();
    });

    it('should handle "none" for stakeholders', async () => {
      await wizard.startRoadmapWizard(sessionId);
      
      await wizard.continueRoadmapWizard(sessionId, {
        name: 'My Product',
        vision: 'Amazing product vision',
        timeHorizon: 'annual',
        owner: 'John Doe'
      });

      const result = await wizard.continueRoadmapWizard(sessionId, {
        stakeholders: 'none'
      });

      expect(result).toContain('Step 3/4');
    });

    it('should return error for invalid session', async () => {
      const result = await wizard.continueRoadmapWizard('invalid-session', {});
      expect(result).toContain('No active roadmap wizard found');
    });
  });

  describe('Initiative Wizard', () => {
    it('should start initiative wizard', async () => {
      const result = await wizard.startInitiativeWizard(
        sessionId,
        'roadmap-123',
        'theme-123'
      );

      expect(result).toContain('Initiative Creation Wizard');
      expect(result).toContain('Step 1/5: Initiative Overview');
      expect(result).toContain('Title');
      expect(result).toContain('Description');
      expect(result).toContain('Key Outcomes');
    });

    it('should progress through initiative wizard steps', async () => {
      // Start wizard
      await wizard.startInitiativeWizard(sessionId, 'roadmap-123', 'theme-123');

      // Step 1 -> Step 2
      const step2Result = await wizard.continueInitiativeWizard(sessionId, {
        title: 'Smart Search',
        description: 'AI-powered search implementation',
        outcomes: ['Instant answers', 'Reduced support']
      });

      expect(step2Result).toContain('Step 2/5: Business Value Assessment');
      expect(step2Result).toContain('User Impact');
      expect(step2Result).toContain('Revenue Impact');

      // Step 2 -> Step 3
      const step3Result = await wizard.continueInitiativeWizard(sessionId, {
        userImpact: 'high',
        revenueImpact: 500000,
        costSavings: 200000,
        strategicValue: 8
      });

      expect(step3Result).toContain('Step 3/5: Effort Estimation');
      expect(step3Result).toContain('Development Weeks');

      // Step 3 -> Step 4
      const step4Result = await wizard.continueInitiativeWizard(sessionId, {
        developmentWeeks: 12,
        designWeeks: 4,
        qaWeeks: 3,
        confidence: 'medium'
      });

      expect(step4Result).toContain('Step 4/5: Risk Assessment');

      // Step 4 -> Step 5
      const step5Result = await wizard.continueInitiativeWizard(sessionId, {
        risks: [{
          description: 'Technical complexity',
          likelihood: 'medium',
          impact: 'high',
          mitigation: 'Technical spike'
        }]
      });

      expect(step5Result).toContain('Step 5/5: Initial Features');
    });

    it('should complete initiative wizard and create initiative', async () => {
      await wizard.startInitiativeWizard(sessionId, 'roadmap-123', 'theme-123');

      // Progress through all steps
      await wizard.continueInitiativeWizard(sessionId, {
        title: 'Smart Search',
        description: 'AI-powered search',
        outcomes: ['Instant answers']
      });

      await wizard.continueInitiativeWizard(sessionId, {
        userImpact: 'high',
        revenueImpact: 500000,
        costSavings: 200000,
        strategicValue: 8
      });

      await wizard.continueInitiativeWizard(sessionId, {
        developmentWeeks: 12,
        designWeeks: 4,
        qaWeeks: 3,
        confidence: 'medium'
      });

      await wizard.continueInitiativeWizard(sessionId, {
        risks: 'none'
      });

      const result = await wizard.continueInitiativeWizard(sessionId, {
        features: [
          {
            name: 'Natural Language Search',
            description: 'NLP search capability',
            value: 85,
            complexity: 'high'
          }
        ]
      });

      expect(result).toContain('Initiative Created Successfully!');
      expect(result).toContain('Smart Search');
      expect(mockRoadmapManager.createInitiative).toHaveBeenCalled();
      expect(mockRoadmapManager.addFeature).toHaveBeenCalled();
    });

    it('should handle invalid roadmap or theme', async () => {
      mockRoadmapManager.getRoadmap.mockResolvedValueOnce(null);
      
      const result = await wizard.startInitiativeWizard(
        sessionId,
        'invalid-roadmap',
        'theme-123'
      );

      expect(result).toContain('Invalid roadmap or theme ID');
    });
  });

  describe('Quick Feature Wizard', () => {
    it('should start quick feature wizard', async () => {
      const result = await wizard.startQuickFeatureWizard(
        sessionId,
        'roadmap-123',
        'init-123'
      );

      expect(result).toContain('Quick Feature Addition');
      expect(result).toContain('Name');
      expect(result).toContain('Description');
      expect(result).toContain('Value');
      expect(result).toContain('Complexity');
      expect(result).toContain('Success Metrics');
    });

    it('should complete quick feature wizard', async () => {
      await wizard.startQuickFeatureWizard(sessionId, 'roadmap-123', 'init-123');

      const result = await wizard.continueQuickFeatureWizard(sessionId, {
        name: 'Real-time Notifications',
        description: 'Push notifications for updates',
        value: 75,
        complexity: 'medium',
        metrics: ['User engagement +30%', 'Response time < 2s']
      });

      expect(result).toContain('Feature Added Successfully!');
      expect(result).toContain('Real-time Notifications');
      expect(mockRoadmapManager.addFeature).toHaveBeenCalledWith({
        roadmapId: 'roadmap-123',
        initiativeId: 'init-123',
        name: 'Real-time Notifications',
        description: 'Push notifications for updates',
        businessValue: {
          score: 75,
          rationale: 'Added via quick wizard',
          metrics: ['User engagement +30%', 'Response time < 2s']
        },
        technicalComplexity: 'medium',
        targetRelease: undefined
      });
    });
  });

  describe('Wizard State Management', () => {
    it('should track active wizards', async () => {
      await wizard.startRoadmapWizard('session-1');
      await wizard.startInitiativeWizard('session-2', 'roadmap-123', 'theme-123');

      const activeWizards = wizard.getActiveWizards();
      expect(activeWizards).toContain('session-1');
      expect(activeWizards).toContain('session-2');
    });

    it('should cancel wizard', async () => {
      await wizard.startRoadmapWizard(sessionId);
      
      const cancelled = wizard.cancelWizard(sessionId);
      expect(cancelled).toBe(true);

      const result = await wizard.continueRoadmapWizard(sessionId, {});
      expect(result).toContain('No active roadmap wizard found');
    });

    it('should not cancel non-existent wizard', () => {
      const cancelled = wizard.cancelWizard('non-existent');
      expect(cancelled).toBe(false);
    });
  });

  describe('Helper Methods', () => {
    it('should derive objectives from context', async () => {
      await wizard.startRoadmapWizard(sessionId);
      
      // Progress to step 4
      await wizard.continueRoadmapWizard(sessionId, {
        name: 'My Product',
        vision: 'Vision',
        timeHorizon: 'annual',
        owner: 'Owner'
      });
      
      await wizard.continueRoadmapWizard(sessionId, {
        stakeholders: []
      });
      
      await wizard.continueRoadmapWizard(sessionId, {
        goal: 'Revenue growth',
        challenges: ['Low conversion'],
        metrics: ['Revenue +50%']
      });

      await wizard.continueRoadmapWizard(sessionId, {
        themes: [{
          name: 'Conversion Optimization',
          description: 'Improve conversion rates',
          priority: 'must-have'
        }]
      });

      // Check that addTheme was called with derived objectives
      const addThemeCall = mockRoadmapManager.addTheme.mock.calls[0][0];
      expect(addThemeCall.objectives).toContain('Drive Revenue growth through conversion optimization');
      expect(addThemeCall.objectives).toContain('Address key challenge: Low conversion');
    });
  });
});