import { WorkflowRequest } from '@models/WorkflowRequest';
import { ApprovalLevel } from '@models/ApprovalLevel';
import { User } from '@models/User';
import { ApprovalStatus, WorkflowStatus } from '../types/common.types';
import { Op } from 'sequelize';
import logger from '@utils/logger';
import { tatSchedulerService } from './tatScheduler.service';
import { calculateElapsedWorkingHours } from '@utils/tatTimeUtils';
import { notificationService } from './notification.service';
import { activityService } from './activity.service';
import dayjs from 'dayjs';
import { emitToRequestRoom } from '../realtime/socket';

export class PauseService {
  /**
   * Pause a workflow at a specific approval level
   * @param requestId - The workflow request ID
   * @param levelId - The approval level ID to pause (optional, pauses current level if not provided)
   * @param userId - The user ID who is pausing
   * @param reason - Reason for pausing
   * @param resumeDate - Date when workflow should auto-resume (max 1 month from now)
   */
  async pauseWorkflow(
    requestId: string,
    levelId: string | null,
    userId: string,
    reason: string,
    resumeDate: Date
  ): Promise<{ workflow: WorkflowRequest; level: ApprovalLevel | null }> {
    try {
      // Validate resume date (max 1 month from now)
      const now = new Date();
      const maxResumeDate = dayjs(now).add(1, 'month').toDate();
      if (resumeDate > maxResumeDate) {
        throw new Error('Resume date cannot be more than 1 month from now');
      }
      if (resumeDate <= now) {
        throw new Error('Resume date must be in the future');
      }

      // Get workflow
      const workflow = await WorkflowRequest.findByPk(requestId);
      if (!workflow) {
        throw new Error('Workflow not found');
      }

      // Check if already paused
      if ((workflow as any).isPaused) {
        throw new Error('Workflow is already paused');
      }

      // Get current approval level
      let level: ApprovalLevel | null = null;
      if (levelId) {
        level = await ApprovalLevel.findByPk(levelId);
        if (!level || (level as any).requestId !== requestId) {
          throw new Error('Approval level not found or does not belong to this workflow');
        }
      } else {
        // Get current active level
        level = await ApprovalLevel.findOne({
          where: {
            requestId,
            status: { [Op.in]: [ApprovalStatus.PENDING, ApprovalStatus.IN_PROGRESS] }
          },
          order: [['levelNumber', 'ASC']]
        });
      }

      if (!level) {
        throw new Error('No active approval level found to pause');
      }

      // Verify user is either the approver for this level OR the initiator
      const isApprover = (level as any).approverId === userId;
      const isInitiator = (workflow as any).initiatorId === userId;
      
      if (!isApprover && !isInitiator) {
        throw new Error('Only the assigned approver or the initiator can pause this workflow');
      }

      // Check if level is already paused
      if ((level as any).isPaused) {
        throw new Error('This approval level is already paused');
      }

      // Calculate elapsed hours before pause
      const priority = ((workflow as any).priority || 'STANDARD').toString().toLowerCase();
      
      // Check if this level was previously paused and resumed
      // If so, we need to account for the previous pauseElapsedHours
      // IMPORTANT: Convert to number to avoid string concatenation (DB returns DECIMAL as string)
      const previousPauseElapsedHours = Number((level as any).pauseElapsedHours || 0);
      const previousResumeDate = (level as any).pauseResumeDate;
      const originalTatStartTime = (level as any).pauseTatStartTime || (level as any).levelStartTime || (level as any).tatStartTime || (level as any).createdAt;
      
      let elapsedHours: number;
      let levelStartTimeForCalculation: Date;
      
      if (previousPauseElapsedHours > 0 && previousResumeDate) {
        // This is a second (or subsequent) pause
        // Calculate: previous elapsed hours + time from resume to now
        levelStartTimeForCalculation = previousResumeDate; // Start from last resume time
        const timeSinceResume = await calculateElapsedWorkingHours(levelStartTimeForCalculation, now, priority);
        elapsedHours = previousPauseElapsedHours + Number(timeSinceResume);
        
        logger.info(`[Pause] Second pause detected - Previous elapsed: ${previousPauseElapsedHours}h, Since resume: ${timeSinceResume}h, Total: ${elapsedHours}h`);
      } else {
        // First pause - calculate from original start time
        levelStartTimeForCalculation = originalTatStartTime;
        elapsedHours = await calculateElapsedWorkingHours(levelStartTimeForCalculation, now, priority);
      }

      // Store TAT snapshot
      const tatSnapshot = {
        levelId: (level as any).levelId,
        levelNumber: (level as any).levelNumber,
        elapsedHours: Number(elapsedHours),
        remainingHours: Math.max(0, Number((level as any).tatHours) - elapsedHours),
        tatPercentageUsed: (Number((level as any).tatHours) > 0 
          ? Math.min(100, Math.round((elapsedHours / Number((level as any).tatHours)) * 100)) 
          : 0),
        pausedAt: now.toISOString(),
        originalTatStartTime: originalTatStartTime // Always use the original start time, not the resume time
      };

      // Update approval level with pause information
      await level.update({
        isPaused: true,
        pausedAt: now,
        pausedBy: userId,
        pauseReason: reason,
        pauseResumeDate: resumeDate,
        pauseTatStartTime: originalTatStartTime, // Always preserve the original start time
        pauseElapsedHours: elapsedHours,
        status: ApprovalStatus.PAUSED
      });

      // Update workflow with pause information
      // Store the current status before pausing so we can restore it on resume
      const currentWorkflowStatus = (workflow as any).status;
      const currentLevel = (workflow as any).currentLevel || (level as any).levelNumber;
      
      await workflow.update({
        isPaused: true,
        pausedAt: now,
        pausedBy: userId,
        pauseReason: reason,
        pauseResumeDate: resumeDate,
        pauseTatSnapshot: {
          ...tatSnapshot,
          previousStatus: currentWorkflowStatus, // Store previous status for resume
          previousCurrentLevel: currentLevel // Store current level to prevent advancement
        },
        status: WorkflowStatus.PAUSED
        // Note: We do NOT update currentLevel here - it should stay at the paused level
      });

      // Cancel TAT jobs for this level
      await tatSchedulerService.cancelTatJobs(requestId, (level as any).levelId);

      // Get user details for notifications
      const user = await User.findByPk(userId);
      const userName = (user as any)?.displayName || (user as any)?.email || 'User';

      // Get initiator
      const initiator = await User.findByPk((workflow as any).initiatorId);
      const initiatorName = (initiator as any)?.displayName || (initiator as any)?.email || 'User';

      // Send notifications
      const requestNumber = (workflow as any).requestNumber;
      const title = (workflow as any).title;

      // Notify initiator only if someone else (approver) paused the request
      // Skip notification if initiator paused their own request
      if (!isInitiator) {
      await notificationService.sendToUsers([(workflow as any).initiatorId], {
        title: 'Workflow Paused',
        body: `Your request "${title}" has been paused by ${userName}. Reason: ${reason}. Will resume on ${dayjs(resumeDate).format('MMM DD, YYYY')}.`,
        requestId,
        requestNumber,
        url: `/request/${requestNumber}`,
        type: 'workflow_paused',
        priority: 'HIGH',
        actionRequired: false,
        metadata: {
          pauseReason: reason,
          resumeDate: resumeDate.toISOString(),
          pausedBy: userId
        }
      });
      }

      // Notify the user who paused (confirmation) - no email for self-action
      await notificationService.sendToUsers([userId], {
        title: 'Workflow Paused Successfully',
        body: `You have paused request "${title}". It will automatically resume on ${dayjs(resumeDate).format('MMM DD, YYYY')}.`,
        requestId,
        requestNumber,
        url: `/request/${requestNumber}`,
        type: 'status_change', // Use status_change to avoid email for self-action
        priority: 'MEDIUM',
        actionRequired: false
      });

      // If initiator paused, notify the current approver
      if (isInitiator && (level as any).approverId) {
        const approver = await User.findByPk((level as any).approverId);
        const approverUserId = (level as any).approverId;
        await notificationService.sendToUsers([approverUserId], {
          title: 'Workflow Paused by Initiator',
          body: `Request "${title}" has been paused by the initiator (${userName}). Reason: ${reason}. Will resume on ${dayjs(resumeDate).format('MMM DD, YYYY')}.`,
          requestId,
          requestNumber,
          url: `/request/${requestNumber}`,
          type: 'workflow_paused',
          priority: 'HIGH',
          actionRequired: false,
          metadata: {
            pauseReason: reason,
            resumeDate: resumeDate.toISOString(),
            pausedBy: userId
          }
        });
      }

      // Log activity
      await activityService.log({
        requestId,
        type: 'paused',
        user: { userId, name: userName },
        timestamp: now.toISOString(),
        action: 'Workflow Paused',
        details: `Workflow paused by ${userName} at level ${(level as any).levelNumber}. Reason: ${reason}. Will resume on ${dayjs(resumeDate).format('MMM DD, YYYY')}.`,
        metadata: {
          levelId: (level as any).levelId,
          levelNumber: (level as any).levelNumber,
          resumeDate: resumeDate.toISOString()
        }
      });

      logger.info(`[Pause] Workflow ${requestId} paused at level ${(level as any).levelNumber} by ${userId}`);

      // Schedule dedicated auto-resume job for this workflow
      try {
        const { pauseResumeQueue } = require('../queues/pauseResumeQueue');
        if (pauseResumeQueue && resumeDate) {
          const delay = resumeDate.getTime() - now.getTime();
          
          if (delay > 0) {
            const jobId = `resume-${requestId}-${(level as any).levelId}`;
            
            await pauseResumeQueue.add(
              'auto-resume-workflow',
              {
                type: 'auto-resume-workflow',
                requestId,
                levelId: (level as any).levelId,
                scheduledResumeDate: resumeDate.toISOString()
              },
              {
                jobId,
                delay, // Exact delay in milliseconds until resume time
                removeOnComplete: true,
                removeOnFail: false
              }
            );
            
            logger.info(`[Pause] Scheduled dedicated auto-resume job ${jobId} for ${resumeDate.toISOString()} (delay: ${Math.round(delay / 1000 / 60)} minutes)`);
          } else {
            logger.warn(`[Pause] Resume date ${resumeDate.toISOString()} is in the past, skipping job scheduling`);
          }
        }
      } catch (queueError) {
        logger.warn(`[Pause] Could not schedule dedicated auto-resume job:`, queueError);
        // Continue with pause even if job scheduling fails (hourly check will handle it as fallback)
      }

      // Emit real-time update to all users viewing this request
      emitToRequestRoom(requestId, 'request:updated', {
        requestId,
        requestNumber: (workflow as any).requestNumber,
        action: 'PAUSE',
        levelNumber: (level as any).levelNumber,
        timestamp: now.toISOString()
      });

      return { workflow, level };
    } catch (error: any) {
      logger.error(`[Pause] Failed to pause workflow:`, error);
      throw error;
    }
  }

  /**
   * Resume a paused workflow
   * @param requestId - The workflow request ID
   * @param userId - The user ID who is resuming (optional, for manual resume)
   * @param notes - Optional notes for the resume action
   */
  async resumeWorkflow(requestId: string, userId?: string, notes?: string): Promise<{ workflow: WorkflowRequest; level: ApprovalLevel | null }> {
    try {
      const now = new Date();

      // Get workflow
      const workflow = await WorkflowRequest.findByPk(requestId);
      if (!workflow) {
        throw new Error('Workflow not found');
      }

      // Check if paused
      if (!(workflow as any).isPaused) {
        throw new Error('Workflow is not paused');
      }

      // Get paused level
      const level = await ApprovalLevel.findOne({
        where: {
          requestId,
          isPaused: true
        },
        order: [['levelNumber', 'ASC']]
      });

      if (!level) {
        throw new Error('Paused approval level not found');
      }

      // Verify user has permission (if manual resume)
      // Both initiator and current approver can resume the workflow
      if (userId) {
        const isApprover = (level as any).approverId === userId;
        const isInitiator = (workflow as any).initiatorId === userId;
        
        if (!isApprover && !isInitiator) {
          throw new Error('Only the assigned approver or the initiator can resume this workflow');
        }
      }

      // Calculate remaining TAT from resume time
      const priority = ((workflow as any).priority || 'STANDARD').toString().toLowerCase();
      const pauseElapsedHours = Number((level as any).pauseElapsedHours || 0);
      const tatHours = Number((level as any).tatHours);
      const remainingHours = Math.max(0, tatHours - pauseElapsedHours);

      // Get which alerts have already been sent (to avoid re-sending on resume)
      const tat50AlertSent = (level as any).tat50AlertSent || false;
      const tat75AlertSent = (level as any).tat75AlertSent || false;
      const tatBreached = (level as any).tatBreached || false;

      // Update approval level - resume TAT
      // IMPORTANT: Keep pauseElapsedHours and store resumedAt (pauseResumeDate repurposed)
      // This allows SLA calculation to correctly add pre-pause elapsed time
      await level.update({
        isPaused: false,
        pausedAt: null as any,
        pausedBy: null as any,
        pauseReason: null as any,
        pauseResumeDate: now, // Store actual resume time (repurposed from scheduled resume date)
        // pauseTatStartTime: null as any, // Keep original TAT start time for reference
        // pauseElapsedHours is intentionally NOT cleared - needed for SLA calculations
        status: ApprovalStatus.IN_PROGRESS,
        tatStartTime: now, // Reset TAT start time to now for new elapsed calculation
        levelStartTime: now // This is the new start time from resume
      });

      // Cancel any scheduled auto-resume job (if exists)
      try {
        const { pauseResumeQueue } = require('../queues/pauseResumeQueue');
        if (pauseResumeQueue) {
          // Try to remove job by specific ID pattern first (more efficient)
          const jobId = `resume-${requestId}-${(level as any).levelId}`;
          try {
            const specificJob = await pauseResumeQueue.getJob(jobId);
            if (specificJob) {
              await specificJob.remove();
              logger.info(`[Pause] Cancelled scheduled auto-resume job ${jobId} for workflow ${requestId}`);
            }
          } catch (err) {
            // Job might not exist, which is fine
          }
          
          // Also check for any other jobs for this request (fallback for old jobs)
          const scheduledJobs = await pauseResumeQueue.getJobs(['delayed', 'waiting']);
          const otherJobs = scheduledJobs.filter((job: any) => 
            job.data.requestId === requestId && job.id !== jobId
          );
          for (const job of otherJobs) {
            await job.remove();
            logger.info(`[Pause] Cancelled legacy auto-resume job ${job.id} for workflow ${requestId}`);
          }
        }
      } catch (queueError) {
        logger.warn(`[Pause] Could not cancel scheduled auto-resume job:`, queueError);
        // Continue with resume even if job cancellation fails
      }

      // Update workflow - restore previous status or default to PENDING
      const pauseSnapshot = (workflow as any).pauseTatSnapshot || {};
      const previousStatus = pauseSnapshot.previousStatus || WorkflowStatus.PENDING;
      
      await workflow.update({
        isPaused: false,
        pausedAt: null as any,
        pausedBy: null as any,
        pauseReason: null as any,
        pauseResumeDate: null as any,
        pauseTatSnapshot: null as any,
        status: previousStatus // Restore previous status (PENDING or IN_PROGRESS)
      });

      // Reschedule TAT jobs from resume time - only for alerts that haven't been sent yet
      if (remainingHours > 0) {
        // Calculate which thresholds are still pending based on remaining time
        const percentageUsedAtPause = tatHours > 0 ? (pauseElapsedHours / tatHours) * 100 : 0;
        
        // Only schedule jobs for thresholds that:
        // 1. Haven't been sent yet
        // 2. Haven't been passed yet (based on percentage used at pause)
        await tatSchedulerService.scheduleTatJobsOnResume(
          requestId,
          (level as any).levelId,
          (level as any).approverId,
          remainingHours, // Remaining TAT hours
          now, // Start from now
          priority as any,
          {
            // Pass which alerts were already sent
            tat50AlertSent: tat50AlertSent,
            tat75AlertSent: tat75AlertSent,
            tatBreached: tatBreached,
            // Pass percentage used at pause to determine which thresholds are still relevant
            percentageUsedAtPause: percentageUsedAtPause
          }
        );
      }

      // Get user details
      const resumeUser = userId ? await User.findByPk(userId) : null;
      const resumeUserName = resumeUser 
        ? ((resumeUser as any)?.displayName || (resumeUser as any)?.email || 'User')
        : 'System (Auto-resume)';

      // Get initiator and paused by user
      const initiator = await User.findByPk((workflow as any).initiatorId);
      const initiatorName = (initiator as any)?.displayName || (initiator as any)?.email || 'User';
      const pausedByUser = (workflow as any).pausedBy 
        ? await User.findByPk((workflow as any).pausedBy)
        : null;
      const pausedByName = pausedByUser 
        ? ((pausedByUser as any)?.displayName || (pausedByUser as any)?.email || 'User')
        : 'Unknown';

      const requestNumber = (workflow as any).requestNumber;
      const title = (workflow as any).title;
      const initiatorId = (workflow as any).initiatorId;
      const approverId = (level as any).approverId;
      const isResumedByInitiator = userId === initiatorId;
      const isResumedByApprover = userId === approverId;

      // Calculate pause duration
      const pausedAt = (level as any).pausedAt || (workflow as any).pausedAt;
      const pauseDurationMs = pausedAt ? now.getTime() - new Date(pausedAt).getTime() : 0;
      const pauseDurationHours = Math.round((pauseDurationMs / (1000 * 60 * 60)) * 100) / 100; // Round to 2 decimal places
      const pauseDuration = pauseDurationHours > 0 ? `${pauseDurationHours} hours` : 'less than 1 hour';

      // Notify initiator only if someone else resumed (or auto-resume)
      // Skip if initiator resumed their own request
      if (!isResumedByInitiator) {
        await notificationService.sendToUsers([initiatorId], {
        title: 'Workflow Resumed',
        body: `Your request "${title}" has been resumed ${userId ? `by ${resumeUserName}` : 'automatically'}.`,
        requestId,
        requestNumber,
        url: `/request/${requestNumber}`,
        type: 'workflow_resumed',
        priority: 'HIGH',
        actionRequired: false,
        metadata: {
          resumedBy: userId ? { userId, name: resumeUserName } : null,
          pauseDuration: pauseDuration
        }
      });
      }

      // Notify approver only if someone else resumed (or auto-resume)
      // Skip if approver resumed the request themselves
      if (!isResumedByApprover && approverId) {
        await notificationService.sendToUsers([approverId], {
        title: 'Workflow Resumed',
        body: `Request "${title}" has been resumed ${userId ? `by ${resumeUserName}` : 'automatically'}. Please continue with your review.`,
        requestId,
        requestNumber,
        url: `/request/${requestNumber}`,
        type: 'workflow_resumed',
        priority: 'HIGH',
        actionRequired: true,
        metadata: {
          resumedBy: userId ? { userId, name: resumeUserName } : null,
          pauseDuration: pauseDuration
        }
      });
      }

      // Send confirmation to the user who resumed (if manual resume) - no email for self-action
      if (userId) {
        await notificationService.sendToUsers([userId], {
          title: 'Workflow Resumed Successfully',
          body: `You have resumed request "${title}". ${isResumedByApprover ? 'Please continue with your review.' : ''}`,
          requestId,
          requestNumber,
          url: `/request/${requestNumber}`,
          type: 'status_change', // Use status_change to avoid email for self-action
          priority: 'MEDIUM',
          actionRequired: isResumedByApprover
        });
      }

      // Log activity with notes
      const resumeDetails = notes 
        ? `Workflow resumed ${userId ? `by ${resumeUserName}` : 'automatically'} at level ${(level as any).levelNumber}. Notes: ${notes}`
        : `Workflow resumed ${userId ? `by ${resumeUserName}` : 'automatically'} at level ${(level as any).levelNumber}.`;
      
      await activityService.log({
        requestId,
        type: 'resumed',
        user: userId ? { userId, name: resumeUserName } : undefined,
        timestamp: now.toISOString(),
        action: 'Workflow Resumed',
        details: resumeDetails,
        metadata: {
          levelId: (level as any).levelId,
          levelNumber: (level as any).levelNumber,
          wasAutoResume: !userId,
          notes: notes || null
        }
      });

      logger.info(`[Pause] Workflow ${requestId} resumed ${userId ? `by ${userId}` : 'automatically'}`);

      // Emit real-time update to all users viewing this request
      emitToRequestRoom(requestId, 'request:updated', {
        requestId,
        requestNumber: (workflow as any).requestNumber,
        action: 'RESUME',
        levelNumber: (level as any).levelNumber,
        timestamp: now.toISOString()
      });

      return { workflow, level };
    } catch (error: any) {
      logger.error(`[Pause] Failed to resume workflow:`, error);
      throw error;
    }
  }

  /**
   * Cancel pause (for retrigger scenario - initiator requests approver to resume)
   * This sends a notification to the approver who paused it
   * @param requestId - The workflow request ID
   * @param userId - The initiator user ID
   */
  async retriggerPause(requestId: string, userId: string): Promise<void> {
    try {
      const workflow = await WorkflowRequest.findByPk(requestId);
      if (!workflow) {
        throw new Error('Workflow not found');
      }

      if (!(workflow as any).isPaused) {
        throw new Error('Workflow is not paused');
      }

      // Verify user is initiator
      if ((workflow as any).initiatorId !== userId) {
        throw new Error('Only the initiator can retrigger a pause');
      }

      const pausedBy = (workflow as any).pausedBy;
      if (!pausedBy) {
        throw new Error('Cannot retrigger - no approver found who paused this workflow');
      }

      // Get user details
      const initiator = await User.findByPk(userId);
      const initiatorName = (initiator as any)?.displayName || (initiator as any)?.email || 'User';

      // Get approver details (who paused the workflow)
      const approver = await User.findByPk(pausedBy);
      const approverName = (approver as any)?.displayName || (approver as any)?.email || 'Approver';

      const requestNumber = (workflow as any).requestNumber;
      const title = (workflow as any).title;

      // Notify approver who paused it
      await notificationService.sendToUsers([pausedBy], {
        title: 'Pause Retrigger Request',
        body: `${initiatorName} is requesting you to cancel the pause and resume work on request "${title}".`,
        requestId,
        requestNumber,
        url: `/request/${requestNumber}`,
        type: 'pause_retrigger_request',
        priority: 'HIGH',
        actionRequired: true
      });

      // Log activity with approver name
      await activityService.log({
        requestId,
        type: 'pause_retriggered',
        user: { userId, name: initiatorName },
        timestamp: new Date().toISOString(),
        action: 'Pause Retrigger Requested',
        details: `${initiatorName} requested ${approverName} to cancel the pause and resume work.`,
        metadata: {
          pausedBy,
          approverName
        }
      });

      logger.info(`[Pause] Pause retrigger requested for workflow ${requestId} by initiator ${userId}`);
    } catch (error: any) {
      logger.error(`[Pause] Failed to retrigger pause:`, error);
      throw error;
    }
  }

  /**
   * Get pause details for a workflow
   */
  async getPauseDetails(requestId: string): Promise<any> {
    try {
      const workflow = await WorkflowRequest.findByPk(requestId);
      if (!workflow) {
        throw new Error('Workflow not found');
      }

      if (!(workflow as any).isPaused) {
        return null;
      }

      const level = await ApprovalLevel.findOne({
        where: {
          requestId,
          isPaused: true
        }
      });

      const pausedByUser = (workflow as any).pausedBy 
        ? await User.findByPk((workflow as any).pausedBy, { attributes: ['userId', 'email', 'displayName'] })
        : null;

      return {
        isPaused: true,
        pausedAt: (workflow as any).pausedAt,
        pausedBy: pausedByUser ? {
          userId: (pausedByUser as any).userId,
          email: (pausedByUser as any).email,
          name: (pausedByUser as any).displayName || (pausedByUser as any).email
        } : null,
        pauseReason: (workflow as any).pauseReason,
        pauseResumeDate: (workflow as any).pauseResumeDate,
        level: level ? {
          levelId: (level as any).levelId,
          levelNumber: (level as any).levelNumber,
          approverName: (level as any).approverName
        } : null
      };
    } catch (error: any) {
      logger.error(`[Pause] Failed to get pause details:`, error);
      throw error;
    }
  }

  /**
   * Check and auto-resume paused workflows whose resume date has passed
   * This is called by a scheduled job
   */
  async checkAndResumePausedWorkflows(): Promise<number> {
    try {
      const now = new Date();

      // Find all paused workflows where resume date has passed
      // Handle backward compatibility: workflow_type column may not exist in old environments
      let pausedWorkflows: WorkflowRequest[];
      try {
        pausedWorkflows = await WorkflowRequest.findAll({
          where: {
            isPaused: true,
            pauseResumeDate: {
              [Op.lte]: now
            }
          }
        });
      } catch (error: any) {
        // If error is due to missing workflow_type column, use raw query
        if (error.message?.includes('workflow_type') || (error.message?.includes('column') && error.message?.includes('does not exist'))) {
          logger.warn('[Pause] workflow_type column not found, using raw query for backward compatibility');
          const { sequelize } = await import('../config/database');
          const { QueryTypes } = await import('sequelize');
          const results = await sequelize.query(`
            SELECT request_id, is_paused, pause_resume_date
            FROM workflow_requests
            WHERE is_paused = true
            AND pause_resume_date <= :now
          `, {
            replacements: { now },
            type: QueryTypes.SELECT
          });
          
          // Convert to WorkflowRequest-like objects
          // results is an array of objects from SELECT query
          pausedWorkflows = (results as any[]).map((r: any) => ({
            requestId: r.request_id,
            isPaused: r.is_paused,
            pauseResumeDate: r.pause_resume_date
          })) as any;
        } else {
          throw error; // Re-throw if it's a different error
        }
      }

      let resumedCount = 0;
      for (const workflow of pausedWorkflows) {
        try {
          await this.resumeWorkflow((workflow as any).requestId);
          resumedCount++;
        } catch (error: any) {
          logger.error(`[Pause] Failed to auto-resume workflow ${(workflow as any).requestId}:`, error);
          // Continue with other workflows
        }
      }

      if (resumedCount > 0) {
        logger.info(`[Pause] Auto-resumed ${resumedCount} workflow(s)`);
      }

      return resumedCount;
    } catch (error: any) {
      logger.error(`[Pause] Failed to check and resume paused workflows:`, error);
      throw error;
    }
  }

  /**
   * Get all paused workflows (for admin/reporting)
   */
  async getPausedWorkflows(): Promise<WorkflowRequest[]> {
    try {
      return await WorkflowRequest.findAll({
        where: {
          isPaused: true
        },
        order: [['pausedAt', 'DESC']]
      });
    } catch (error: any) {
      logger.error(`[Pause] Failed to get paused workflows:`, error);
      throw error;
    }
  }
}

export const pauseService = new PauseService();

