import { ipcMain } from 'electron';
import type { BrowserWindow, IpcMainInvokeEvent } from 'electron';
import { DIContainer } from './di-container';
import type { HostedSessionConfig } from '@/packages/domain/entities/HostedSessionConfig';
import { StepId } from '@/packages/domain/value-objects/StepId';

let progressMonitorInterval: NodeJS.Timeout | null = null;

export function setupIpcHandlers(mainWindow: BrowserWindow): void {
  const container = DIContainer.getInstance();
  const startAutomationUseCase = container.getStartAutomationUseCase();
  const sessionRepository = container.getSessionRepository();
  const automationEngine = container.getAutomationEngine();
  const logger = container.getLogger();

  ipcMain.handle('start-automation', async (_event: IpcMainInvokeEvent, config: HostedSessionConfig) => {
    try {
      logger.info('Starting automation', { sessionName: config.sessionName });
      
      // Clear any existing progress interval
      if (progressMonitorInterval) {
        clearInterval(progressMonitorInterval);
        progressMonitorInterval = null;
      }
      
      // Connect to browser first (required for dev mode)
      const connectionResult = await container.initializeBrowserConnection();
      if (!connectionResult.success) {
        logger.error('Browser connection failed', undefined, { errorMessage: connectionResult.error });
        return { success: false, error: connectionResult.error };
      }
      logger.info('Browser connection established');

      const result = await startAutomationUseCase.execute(config);
      logger.info('Automation session created', { sessionId: result.sessionId });
      
      const session = await sessionRepository.findById(result.sessionId);
      
      if (session) {
        // Start the automation by executing step 1
        logger.info('Executing step 1');
        await automationEngine.executeStep(StepId.create(1), config);
      }
      
      // Set up progress monitoring
      progressMonitorInterval = setInterval(async () => {
        const updatedSession = await sessionRepository.findById(result.sessionId);
        if (!updatedSession) {
          if (progressMonitorInterval) {
            clearInterval(progressMonitorInterval);
            progressMonitorInterval = null;
          }
          return;
        }

        mainWindow.webContents.send('session-progress', {
          sessionId: result.sessionId,
          currentStep: updatedSession.currentStep.value,
          state: updatedSession.state.value,
          completedSteps: Array.from({ length: updatedSession.currentStep.value - 1 }, (_, i) => i + 1),
          hasError: updatedSession.errorMessage !== undefined,
          errorMessage: updatedSession.errorMessage || null
        });

        if (updatedSession.state.value === 'COMPLETED' ||
            updatedSession.state.value === 'FAILED' ||
            updatedSession.state.value === 'STOPPED_AT_STEP_18') {
          logger.info('Automation ended', { state: updatedSession.state.value });
          if (progressMonitorInterval) {
            clearInterval(progressMonitorInterval);
            progressMonitorInterval = null;
          }
        }
      }, 100);

      return {
        success: true,
        sessionId: result.sessionId
      };
    } catch (error) {
      const err = error instanceof Error ? error : new Error('Unknown error');
      logger.error('Automation failed', err);
      return {
        success: false,
        error: err.message
      };
    }
  });

  ipcMain.handle('get-session-status', async (_event: IpcMainInvokeEvent, sessionId: string) => {
    const session = await sessionRepository.findById(sessionId);
    if (!session) {
      return { found: false };
    }

    return {
      found: true,
      currentStep: session.currentStep.value,
      state: session.state.value,
      completedSteps: Array.from({ length: session.currentStep.value - 1 }, (_, i) => i + 1),
      hasError: session.errorMessage !== undefined,
      errorMessage: session.errorMessage || null
    };
  });

  ipcMain.handle('pause-automation', async (_event: IpcMainInvokeEvent, _sessionId: string) => {
    return { success: false, error: 'Pause not implemented in POC' };
  });

  ipcMain.handle('resume-automation', async (_event: IpcMainInvokeEvent, _sessionId: string) => {
    return { success: false, error: 'Resume not implemented in POC' };
  });

  ipcMain.handle('stop-automation', async (_event: IpcMainInvokeEvent, sessionId: string) => {
    try {
      logger.info('Stopping automation', { sessionId });
      
      // Clear progress monitoring interval
      if (progressMonitorInterval) {
        clearInterval(progressMonitorInterval);
        progressMonitorInterval = null;
        logger.info('Progress monitor cleared');
      }
      
      // Stop the automation engine interval
      automationEngine.stopAutomation();
      logger.info('Automation engine stopped');
      
      // Update session state to failed with user stop reason
      const session = await sessionRepository.findById(sessionId);
      if (session) {
        session.fail('User stopped automation');
        await sessionRepository.update(session);
        logger.info('Session marked as failed', { sessionId });
      }
      
      return { success: true };
    } catch (error) {
      const err = error instanceof Error ? error : new Error('Unknown error');
      logger.error('Stop automation failed', err);
      return {
        success: false,
        error: err.message
      };
    }
  });
}