import { IAutomationEngine, ValidationResult } from '../../../packages/application/ports/IAutomationEngine';
import { HostedSessionConfig } from '../../../packages/domain/entities/HostedSessionConfig';
import { StepId } from '../../../packages/domain/value-objects/StepId';
import { IBrowserAutomation } from '../../../packages/application/ports/IBrowserAutomation';
import { ISessionRepository } from '../../../packages/application/ports/ISessionRepository';
import { getStepName } from './selectors/IRacingSelectorMap';

export class MockAutomationEngineAdapter implements IAutomationEngine {
  private automationInterval: NodeJS.Timeout | null = null;

  constructor(
    private readonly browserAutomation: IBrowserAutomation,
    private readonly sessionRepository: ISessionRepository
  ) {}

  async validateConfiguration(config: HostedSessionConfig): Promise<ValidationResult> {
    if (!config.sessionName || config.sessionName.trim() === '') {
      return { isValid: false, error: 'Session name is required' };
    }
    if (!config.trackId || config.trackId.trim() === '') {
      return { isValid: false, error: 'Track ID is required' };
    }
    if (!config.carIds || config.carIds.length === 0) {
      return { isValid: false, error: 'At least one car must be selected' };
    }
    return { isValid: true };
  }

  async executeStep(stepId: StepId, config: HostedSessionConfig): Promise<void> {
    const sessions = await this.sessionRepository.findAll();
    const session = sessions[0];
    if (!session) {
      throw new Error('No active session found');
    }

    // Start session if it's at step 1 and pending
    if (session.state.isPending() && stepId.value === 1) {
      session.start();
      await this.sessionRepository.update(session);
      
      // Start automated progression
      this.startAutomation(config);
    }
  }

  private startAutomation(config: HostedSessionConfig): void {
    this.automationInterval = setInterval(async () => {
      try {
        const sessions = await this.sessionRepository.findAll();
        const session = sessions[0];
        
        if (!session || !session.state.isInProgress()) {
          if (this.automationInterval) {
            clearInterval(this.automationInterval);
            this.automationInterval = null;
          }
          return;
        }

        const currentStep = session.currentStep;
        
        // Execute current step using the browser automation
        if (this.browserAutomation.executeStep) {
          // Use real workflow automation with IRacingSelectorMap
          const result = await this.browserAutomation.executeStep(currentStep, config as Record<string, unknown>);
          if (!result.success) {
            console.error(`Step ${currentStep.value} (${getStepName(currentStep.value)}) failed:`, result.error);
            // Continue anyway for now - in production we might want to pause or retry
          }
        } else {
          // Fallback for adapters without executeStep (e.g., MockBrowserAutomationAdapter)
          await this.browserAutomation.navigateToPage(`step-${currentStep.value}`);
        }
        
        // Transition to next step if not final
        if (!currentStep.isFinalStep()) {
          session.transitionToStep(currentStep.next());
          await this.sessionRepository.update(session);
        } else {
          // Stop at step 18
          if (this.automationInterval) {
            clearInterval(this.automationInterval);
            this.automationInterval = null;
          }
        }
      } catch (error) {
        console.error('Automation error:', error);
        if (this.automationInterval) {
          clearInterval(this.automationInterval);
          this.automationInterval = null;
        }
      }
    }, 500); // Execute each step every 500ms
  }

  public stopAutomation(): void {
    if (this.automationInterval) {
      clearInterval(this.automationInterval);
      this.automationInterval = null;
    }
  }
}