import type { IMochaIntegration, EnvironmentValidation, DependencyCheck } from '../../interfaces/infrastructure/mocha-integration';
import type { MultiSessionConfig } from '../../interfaces/core/types';

declare global {
  interface Window {
    // Mocha Multiple Sessions Library - Complete interface
    MochaMultipleSessions?: {
      testSessionSetup: (config: any) => void;
      onAnySessionEvent: (callback: (event: any) => void) => () => void;
      testSession: (label: string, setupFn: () => void, options?: any) => Promise<string>;
      runSession: (label: string) => Promise<any>;
      runAllSessions: () => Promise<any[]>;
    };
    
    // Mocha Detailed Reporter
    MochaDetailedReporter?: {
      DetailedJsonReporter: any;
    };
    
    // Basic dependencies
    Mocha?: any;
    mocha?: any;
    chai?: any;
  }
}

export class MochaIntegration implements IMochaIntegration {
  private isConfiguredFlag = false;
  private currentConfig: any = null;

  setupTestEnvironment(config: MultiSessionConfig): void {
    this.validateEnvironment();
    
    const defaultConfig = {
      createMochaInstance: (sessionLabel: string) => {
        const resultKey = config.windowVariablePrefix + sessionLabel.replace(/\s+/g, '_').replace(/-/g, '_');
        
        if (!window.MochaDetailedReporter) {
          throw new Error('MochaDetailedReporter not available');
        }
        
        return new window.Mocha!({
          ui: 'bdd',
          reporter: window.MochaDetailedReporter.DetailedJsonReporter,
          reporterOptions: {
            outputToWindow: 'true',
            windowVariableName: resultKey,
            captureConsoleLog: config.captureConsoleLog ? 'true' : 'false',
            sourceCode: config.sourceCode ? 'true' : 'false',
            attachStats: config.attachStats ? 'true' : 'false'
          }
        });
      },
      
      injectGlobals: (mochaInstance: any) => {
        mochaInstance.suite.emit('pre-require', window, null, mochaInstance);
        if (window.chai) {
          (window as any).expect = window.chai.expect;
        }
      }
    };

    // Use provided config or defaults
    const finalConfig = {
      createMochaInstance: config.createMochaInstance || defaultConfig.createMochaInstance,
      injectGlobals: config.injectGlobals || defaultConfig.injectGlobals
    };
    
    // Setup with mocha-multiple-sessions
    if (window.MochaMultipleSessions?.testSessionSetup) {
      window.MochaMultipleSessions.testSessionSetup(finalConfig);
      this.currentConfig = finalConfig;
      this.isConfiguredFlag = true;
    } else {
      throw new Error('MochaMultipleSessions library not available');
    }
  }

  isConfigured(): boolean {
    return this.isConfiguredFlag;
  }

  getConfiguration(): any {
    return this.currentConfig;
  }

  integrateWithExistingLibrary(): void {
    if (!window.MochaMultipleSessions) {
      throw new Error('MochaMultipleSessions library not found');
    }
    
    // Integration is handled in setupTestEnvironment
  }

  setupDefaultReporter(sessionLabel: string): any {
    const resultKey = `mochaSession__${sessionLabel.replace(/\s+/g, '_').replace(/-/g, '_')}`;
    
    if (!window.MochaDetailedReporter) {
      throw new Error('MochaDetailedReporter not available');
    }
    
    return new window.Mocha!({
      ui: 'bdd',
      reporter: window.MochaDetailedReporter.DetailedJsonReporter,
      reporterOptions: {
        outputToWindow: 'true',
        windowVariableName: resultKey,
        captureConsoleLog: 'true',
        sourceCode: 'true',
        attachStats: 'true'
      }
    });
  }

  bridgeSessionEvents(): void {
    // This would be implemented if we need to bridge events
    // For now, the existing library handles events
  }

  validateEnvironment(): EnvironmentValidation {
    const errors: string[] = [];
    const warnings: string[] = [];
    const missing: string[] = [];

    const deps = this.checkDependencies();
    
    if (!deps.mocha) {
      errors.push('Mocha library not found');
      missing.push('mocha');
    }
    
    if (!deps.chai) {
      warnings.push('Chai library not found - tests may not work properly');
      missing.push('chai');
    }
    
    if (!deps.detailedReporter) {
      errors.push('MochaDetailedReporter not found');
      missing.push('mocha-detailed-json-reporter');
    }
    
    if (!deps.multipleSessionsLibrary) {
      errors.push('MochaMultipleSessions library not found');
      missing.push('mocha-multiple-sessions-ts');
    }

    const validation: EnvironmentValidation = {
      isValid: errors.length === 0,
      errors,
      warnings,
      missingDependencies: missing
    };

    if (!validation.isValid) {
      throw new Error(`Environment validation failed: ${errors.join(', ')}`);
    }

    return validation;
  }

  checkDependencies(): DependencyCheck {
    return {
      mocha: typeof window.Mocha !== 'undefined' && typeof window.mocha !== 'undefined',
      chai: typeof window.chai !== 'undefined',
      detailedReporter: typeof window.MochaDetailedReporter !== 'undefined',
      multipleSessionsLibrary: typeof window.MochaMultipleSessions !== 'undefined',
      reporterUI: typeof (window as any).MochaDetailedReporterUI !== 'undefined'
    };
  }
}
