// Workflow Engine Service
import { v4 as uuidv4 } from 'uuid';
// State machine for IRU qualification and deployment workflow

import prisma from '@/shared/database/prisma';
import { logger } from '@/infrastructure/monitoring/logger';

export enum QualificationState {
  SUBMITTED = 'submitted',
  ACKNOWLEDGED = 'acknowledged',
  IN_REVIEW = 'in_review',
  QUALIFIED = 'qualified',
  REJECTED = 'rejected',
}

export enum DeploymentState {
  PENDING = 'pending',
  PROVISIONING = 'provisioning',
  DEPLOYING = 'deploying',
  CONFIGURING = 'configuring',
  TESTING = 'testing',
  ACTIVE = 'active',
  FAILED = 'failed',
}

export interface WorkflowState {
  inquiryId: string;
  qualificationState: QualificationState;
  deploymentState?: DeploymentState;
  currentStep: string;
  completedSteps: string[];
  nextSteps: string[];
  metadata: Record<string, any>;
}

export class WorkflowEngine {
  /**
   * Transition qualification state
   */
  async transitionQualification(
    inquiryId: string,
    fromState: QualificationState,
    toState: QualificationState,
    metadata?: Record<string, any>
  ): Promise<WorkflowState> {
    // Validate transition
    const validTransitions: Record<QualificationState, QualificationState[]> = {
      [QualificationState.SUBMITTED]: [QualificationState.ACKNOWLEDGED, QualificationState.REJECTED],
      [QualificationState.ACKNOWLEDGED]: [QualificationState.IN_REVIEW, QualificationState.REJECTED],
      [QualificationState.IN_REVIEW]: [QualificationState.QUALIFIED, QualificationState.REJECTED],
      [QualificationState.QUALIFIED]: [],
      [QualificationState.REJECTED]: [],
    };

    if (!validTransitions[fromState].includes(toState)) {
      throw new Error(`Invalid transition from ${fromState} to ${toState}`);
    }

    // Persist state transition
    try {
      await prisma.iruWorkflowState.upsert({
        where: {
          inquiryId,
        },
        create: {
          id: uuidv4(),
          inquiryId,
          qualificationState: toState,
          currentStep: this.getCurrentStep(toState),
          completedSteps: this.getCompletedSteps(toState),
          nextSteps: this.getNextSteps(toState),
          metadata: metadata || {},
          createdAt: new Date(),
          updatedAt: new Date(),
        },
        update: {
          qualificationState: toState,
          currentStep: this.getCurrentStep(toState),
          completedSteps: this.getCompletedSteps(toState),
          nextSteps: this.getNextSteps(toState),
          metadata: {
            ...((await prisma.iruWorkflowState.findUnique({ where: { inquiryId } }))?.metadata as WorkflowMetadata || {}),
            ...(metadata || {}),
          },
          updatedAt: new Date(),
        },
      });

      logger.info('Workflow state transition persisted', {
        inquiryId,
        fromState,
        toState,
      });
    } catch (error) {
      logger.error('Failed to persist workflow state transition', {
        inquiryId,
        error: error instanceof Error ? error.message : 'Unknown error',
      });
    }

    // Trigger workflow actions based on state
    if (toState === QualificationState.QUALIFIED) {
      // Trigger agreement generation
      try {
        const { agreementGenerator } = await import('@/core/iru/agreement/agreement-generator.service');
        const inquiry = await prisma.iruInquiry.findUnique({
          where: { inquiryId },
          include: {
            subscription: {
              select: {
                subscriptionId: true,
              },
            },
          },
        });

        if (inquiry?.subscription) {
          await agreementGenerator.generateAgreement({
            subscriptionId: inquiry.subscription.subscriptionId,
          });
          logger.info('Agreement generated after qualification', { inquiryId });
        }
      } catch (error) {
        logger.error('Failed to generate agreement after qualification', {
          inquiryId,
          error: error instanceof Error ? error.message : 'Unknown error',
        });
      }
    } else if (toState === QualificationState.REJECTED) {
      // Send rejection notification
      try {
        const { notificationService } = await import('@/core/iru/notifications/notification.service');
        const inquiry = await prisma.iruInquiry.findUnique({
          where: { inquiryId },
          select: {
            contactEmail: true,
            organizationName: true,
          },
        });

        if (inquiry) {
          await notificationService.sendNotification({
            recipient: inquiry.contactEmail,
            recipientType: 'email',
            template: 'qualification-rejected',
            variables: {
              inquiryId,
              organizationName: inquiry.organizationName,
            },
          });
          logger.info('Rejection notification sent', { inquiryId });
        }
      } catch (error) {
        logger.error('Failed to send rejection notification', {
          inquiryId,
          error: error instanceof Error ? error.message : 'Unknown error',
        });
      }
    }

    return {
      inquiryId,
      qualificationState: toState,
      currentStep: this.getCurrentStep(toState),
      completedSteps: this.getCompletedSteps(toState),
      nextSteps: this.getNextSteps(toState),
      metadata: metadata || {},
    };
  }

  /**
   * Get current step
   */
  private getCurrentStep(state: QualificationState): string {
    const stepMap: Record<QualificationState, string> = {
      [QualificationState.SUBMITTED]: 'Inquiry Submitted',
      [QualificationState.ACKNOWLEDGED]: 'Inquiry Acknowledged',
      [QualificationState.IN_REVIEW]: 'Qualification Review',
      [QualificationState.QUALIFIED]: 'Qualification Complete',
      [QualificationState.REJECTED]: 'Qualification Rejected',
    };
    return stepMap[state];
  }

  /**
   * Get completed steps
   */
  private getCompletedSteps(state: QualificationState): string[] {
    const allSteps = [
      'Inquiry Submitted',
      'Inquiry Acknowledged',
      'Qualification Review',
      'Qualification Complete',
    ];

    const stateIndex: Record<QualificationState, number> = {
      [QualificationState.SUBMITTED]: 0,
      [QualificationState.ACKNOWLEDGED]: 1,
      [QualificationState.IN_REVIEW]: 2,
      [QualificationState.QUALIFIED]: 3,
      [QualificationState.REJECTED]: 2,
    };

    return allSteps.slice(0, stateIndex[state] + 1);
  }

  /**
   * Get next steps
   */
  private getNextSteps(state: QualificationState): string[] {
    if (state === QualificationState.QUALIFIED) {
      return ['Agreement Generation', 'E-Signature', 'Technical Onboarding', 'Deployment'];
    }
    if (state === QualificationState.REJECTED) {
      return ['Review Rejection Reasons', 'Resubmit Inquiry'];
    }
    return [];
  }
}

export const workflowEngine = new WorkflowEngine();
