/**
 * Dealer Claim Email Service
 * 
 * Dedicated service for handling email template selection and sending
 * for dealer claim workflows (CLAIM_MANAGEMENT).
 * 
 * This service is separate from the main notification service to:
 * - Isolate dealer claim-specific logic
 * - Prevent breaking custom workflows
 * - Handle dynamic step identification (by levelName, not levelNumber)
 * - Support additional approvers between steps
 */

import { ApprovalLevel } from '@models/ApprovalLevel';
import { User } from '@models/User';
import logger from '@utils/logger';
import { IWorkflowEmailService } from './workflowEmail.interface';
import { emailNotificationService } from './emailNotification.service';

export class DealerClaimEmailService implements IWorkflowEmailService {
  /**
   * Determine and send the appropriate email template for dealer claim assignment notifications
   * Handles:
   * - Dealer Proposal Step (Step 1)
   * - Dealer Completion Documents Step (Step 4)
   * - Standard approval steps (Steps 2, 3, 5)
   * - Additional approvers (always use standard template)
   */
  async sendAssignmentEmail(
    requestData: any,
    approverUser: User,
    initiatorData: any,
    currentLevel: ApprovalLevel | null,
    allLevels: ApprovalLevel[]
  ): Promise<void> {
    try {
      // SAFETY CHECK: Ensure this is actually a dealer claim workflow
      // This prevents dealer-specific logic from being applied to custom workflows
      const workflowType = requestData.workflowType || requestData.templateType || 'CUSTOM';
      if (workflowType !== 'CLAIM_MANAGEMENT') {
        logger.warn(`[DealerClaimEmail] ⚠️ Wrong workflow type (${workflowType}) - falling back to standard email. This service should only handle CLAIM_MANAGEMENT workflows.`);
        // Fall back to standard approval email
        const approverData = approverUser.toJSON();
        if (currentLevel) {
          (approverData as any).levelNumber = (currentLevel as any).levelNumber;
        }
        const isMultiLevel = allLevels.length > 1;
        const { emailNotificationService } = await import('./emailNotification.service');
        await emailNotificationService.sendApprovalRequest(
          requestData,
          approverData,
          initiatorData,
          isMultiLevel,
          isMultiLevel ? allLevels.map((l: any) => l.toJSON()) : undefined
        );
        return;
      }

      if (!currentLevel) {
        logger.warn(`[DealerClaimEmail] No current level found, sending standard approval email`);
        await this.sendStandardApprovalEmail(requestData, approverUser, initiatorData, currentLevel);
        return;
      }

      // Reload level from DB to ensure we have the latest levelName
      const level = await ApprovalLevel.findByPk((currentLevel as any).levelId) || currentLevel;
      const levelName = (level.levelName || '').toLowerCase().trim();
      
      logger.info(`[DealerClaimEmail] Level: "${level.levelName}" (${level.levelNumber}), Approver: ${approverUser.email}`);

      // Check if it's an additional approver (always use standard template)
      // Additional approvers can have various levelName formats:
      // - "Additional Approver" (from addApproverAtLevel)
      // - "Additional Approver - Level X" (fallback)
      // - "Additional Approver - ${designation}" (from addApproverAtLevel with designation)
      // - Custom stepName from frontend (when isAdditional=true)
      const isAdditionalApprover = levelName.includes('additional approver') || 
                                   (levelName.includes('additional') && levelName.includes('approver'));
      
      if (isAdditionalApprover) {
        logger.info(`[DealerClaimEmail] ✅ Additional approver detected - sending standard approval email`);
        await this.sendStandardApprovalEmail(requestData, approverUser, initiatorData, level);
        return;
      }

      // SIMPLE DETECTION: Use levelName as the primary source of truth
      // Level names are always set correctly: 
      // - "Dealer Proposal Submission" (Step 1)
      // - "Dealer Completion Documents" (Step 4)
      const isDealerProposalStep = levelName.includes('dealer') && levelName.includes('proposal');
      const isDealerCompletionStep = levelName.includes('dealer') && 
                                     (levelName.includes('completion') || levelName.includes('documents')) &&
                                     !levelName.includes('proposal'); // Explicitly exclude proposal

      // Route to appropriate template
      if (isDealerCompletionStep) {
        logger.info(`[DealerClaimEmail] ✅ DEALER COMPLETION step - sending completion documents required email`);
        await this.sendDealerCompletionRequiredEmail(requestData, approverUser, initiatorData, level);
      } else if (isDealerProposalStep) {
        logger.info(`[DealerClaimEmail] ✅ DEALER PROPOSAL step - sending proposal required email`);
        await this.sendDealerProposalRequiredEmail(requestData, approverUser, initiatorData, level);
      } else {
        logger.info(`[DealerClaimEmail] ✅ STANDARD approval step - sending standard approval email`);
        await this.sendStandardApprovalEmail(requestData, approverUser, initiatorData, level);
      }
    } catch (error) {
      logger.error(`[DealerClaimEmail] Error sending assignment email:`, error);
      throw error;
    }
  }

  /**
   * Send dealer proposal required email
   */
  private async sendDealerProposalRequiredEmail(
    requestData: any,
    dealerUser: User,
    initiatorData: any,
    currentLevel: ApprovalLevel | null
  ): Promise<void> {
    logger.info(`[DealerClaimEmail] Sending dealer proposal required email to ${dealerUser.email}`);
    
    // Get claim details for dealer-specific data
    const { DealerClaimDetails } = await import('@models/DealerClaimDetails');
    const claimDetails = await DealerClaimDetails.findOne({
      where: { requestId: requestData.requestId }
    });
    
    const claimData = claimDetails ? (claimDetails as any).toJSON() : {};
    
    await emailNotificationService.sendDealerProposalRequired(
      requestData,
      dealerUser.toJSON(),
      initiatorData,
      {
        activityName: claimData.activityName || requestData.title,
        activityType: claimData.activityType || 'N/A',
        activityDate: claimData.activityDate,
        location: claimData.location,
        estimatedBudget: claimData.estimatedBudget,
        dealerName: claimData.dealerName,
        tatHours: currentLevel ? (currentLevel as any).tatHours : undefined
      }
    );
  }

  /**
   * Send dealer completion documents required email
   */
  private async sendDealerCompletionRequiredEmail(
    requestData: any,
    dealerUser: User,
    initiatorData: any,
    currentLevel: ApprovalLevel | null
  ): Promise<void> {
    logger.info(`[DealerClaimEmail] Sending dealer completion documents required email to ${dealerUser.email}`);
    
    // Get claim details for dealer-specific data
    const { DealerClaimDetails } = await import('@models/DealerClaimDetails');
    const claimDetails = await DealerClaimDetails.findOne({
      where: { requestId: requestData.requestId }
    });
    
    const claimData = claimDetails ? (claimDetails as any).toJSON() : {};
    
    // Use dedicated completion documents required template
    await emailNotificationService.sendDealerCompletionRequired(
      requestData,
      dealerUser.toJSON(),
      initiatorData,
      {
        activityName: claimData.activityName || requestData.title,
        activityType: claimData.activityType || 'N/A',
        activityDate: claimData.activityDate,
        location: claimData.location,
        estimatedBudget: claimData.estimatedBudget,
        dealerName: claimData.dealerName,
        tatHours: currentLevel ? (currentLevel as any).tatHours : undefined
      }
    );
  }

  /**
   * Send standard approval email (single approver template)
   * For dealer claim workflows, enrich with dealer claim-specific details
   */
  private async sendStandardApprovalEmail(
    requestData: any,
    approverUser: User,
    initiatorData: any,
    currentLevel: ApprovalLevel | null
  ): Promise<void> {
    logger.info(`[DealerClaimEmail] Sending enhanced approval email to ${approverUser.email}`);
    
    // Get dealer claim details to enrich the email
    const { DealerClaimDetails } = await import('@models/DealerClaimDetails');
    const { DealerProposalDetails } = await import('@models/DealerProposalDetails');
    
    const claimDetails = await DealerClaimDetails.findOne({
      where: { requestId: requestData.requestId }
    });
    
    const proposalDetails = await DealerProposalDetails.findOne({
      where: { requestId: requestData.requestId }
    });
    
    // Determine stage-specific instructions
    let stageInstructions = '';
    const name = (currentLevel?.levelName || '').toLowerCase();
    
    if (name.includes('evaluation') || name.includes('requestor evaluation')) {
      stageInstructions = 'Please evaluate the proposal submitted by the dealer. Verify the activity details and estimated budget.';
    } else if (name.includes('lead') || name.includes('department lead')) {
      stageInstructions = 'The requestor has evaluated this proposal and recommended it for your approval. Please review and provide your authorization.';
    } else if (name.includes('claim approval') && name.includes('requestor')) {
      stageInstructions = 'The dealer has submitted completion documents. Please verify the expenses and documents before providing final claim approval.';
    }

    // Enrich requestData with dealer claim-specific information
    const enrichedRequestData = {
      ...requestData,
      // Add dealer claim details to description if not already present
      description: this.enrichDescriptionWithClaimDetails(
        requestData.description || '',
        claimDetails,
        proposalDetails
      ),
      // Add activity information
      activityName: claimDetails ? (claimDetails as any).activityName : undefined,
      activityType: claimDetails ? (claimDetails as any).activityType : undefined,
      dealerName: claimDetails ? (claimDetails as any).dealerName : undefined,
      dealerCode: claimDetails ? (claimDetails as any).dealerCode : undefined,
      location: claimDetails ? (claimDetails as any).location : undefined,
      proposalBudget: proposalDetails ? (proposalDetails as any).totalEstimatedBudget : undefined
    };
    
    const approverData = approverUser.toJSON();
    
    // Add level number if available
    if (currentLevel) {
      (approverData as any).levelNumber = (currentLevel as any).levelNumber;
    }

    // Always use single approver template for dealer claim workflows
    // (not multi-level, even if there are multiple steps)
    await emailNotificationService.sendApprovalRequest(
      enrichedRequestData,
      approverData,
      initiatorData,
      false, // isMultiLevel = false for dealer claim workflows
      undefined, // No approval chain needed
      stageInstructions // Pass as customMessage (contextual instruction)
    );
  }

  /**
   * Enrich request description with dealer claim-specific details
   */
  private enrichDescriptionWithClaimDetails(
    existingDescription: string,
    claimDetails: any,
    proposalDetails: any
  ): string {
    if (!claimDetails) {
      return existingDescription;
    }

    const claimData = (claimDetails as any).toJSON();
    let enrichedDescription = existingDescription || '';
    
    // Add dealer claim details section if not already present
    const detailsSection = `
      <div style="margin-top: 20px; padding: 15px; background-color: #f8f9fa; border-left: 4px solid #667eea; border-radius: 4px;">
        <h3 style="margin: 0 0 15px; color: #333333; font-size: 16px; font-weight: 600;">Claim Details:</h3>
        <table style="width: 100%; border-collapse: collapse;">
          ${claimData.activityName ? `
          <tr>
            <td style="padding: 8px 0; color: #666666; font-size: 14px; width: 140px;"><strong>Activity Name:</strong></td>
            <td style="padding: 8px 0; color: #333333; font-size: 14px;">${claimData.activityName}</td>
          </tr>
          ` : ''}
          ${claimData.activityType ? `
          <tr>
            <td style="padding: 8px 0; color: #666666; font-size: 14px;"><strong>Activity Type:</strong></td>
            <td style="padding: 8px 0; color: #333333; font-size: 14px;">${claimData.activityType}</td>
          </tr>
          ` : ''}
          ${claimData.dealerName ? `
          <tr>
            <td style="padding: 8px 0; color: #666666; font-size: 14px;"><strong>Dealer:</strong></td>
            <td style="padding: 8px 0; color: #333333; font-size: 14px;">${claimData.dealerName}${claimData.dealerCode ? ` (${claimData.dealerCode})` : ''}</td>
          </tr>
          ` : ''}
          ${claimData.location ? `
          <tr>
            <td style="padding: 8px 0; color: #666666; font-size: 14px;"><strong>Location:</strong></td>
            <td style="padding: 8px 0; color: #333333; font-size: 14px;">${claimData.location}</td>
          </tr>
          ` : ''}
          ${claimData.activityDate ? `
          <tr>
            <td style="padding: 8px 0; color: #666666; font-size: 14px;"><strong>Activity Date:</strong></td>
            <td style="padding: 8px 0; color: #333333; font-size: 14px;">${new Date(claimData.activityDate).toLocaleDateString('en-IN', { year: 'numeric', month: 'long', day: 'numeric' })}</td>
          </tr>
          ` : ''}
          ${proposalDetails && (proposalDetails as any).totalEstimatedBudget ? `
          <tr>
            <td style="padding: 8px 0; color: #666666; font-size: 14px;"><strong>Proposed Budget:</strong></td>
            <td style="padding: 8px 0; color: #333333; font-size: 14px; font-weight: 600;">₹${Number((proposalDetails as any).totalEstimatedBudget).toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</td>
          </tr>
          ` : ''}
        </table>
      </div>
    `;
    
    // Append details section if not already in description
    if (!enrichedDescription.includes('Claim Details:') && !enrichedDescription.includes('Activity Name:')) {
      enrichedDescription += detailsSection;
    }
    
    return enrichedDescription;
  }
}

export const dealerClaimEmailService = new DealerClaimEmailService();

