import {
    TERMINATION_STAGES,
    RESIGNATION_STAGES,
    CONSTITUTIONAL_STAGES,
    RELOCATION_STAGES,
    REQUEST_TYPES,
    OFFBOARDING_ACTIONS,
    AUDIT_ACTIONS
} from '../config/constants.js';

/**
 * Resolves the previous stage for a given offboarding module and its current stage.
 * Used for Send Back actions to determine where to roll back the workflow.
 */
export const getPreviousStage = (requestType: string, currentStage: string): string | null => {
    switch (requestType) {
        case REQUEST_TYPES.TERMINATION: {
            const flow: Record<string, string> = {
                [TERMINATION_STAGES.RBM_REVIEW]: TERMINATION_STAGES.SUBMITTED,
                [TERMINATION_STAGES.ZBH_REVIEW]: TERMINATION_STAGES.RBM_REVIEW,
                [TERMINATION_STAGES.DD_LEAD_REVIEW]: TERMINATION_STAGES.ZBH_REVIEW,
                [TERMINATION_STAGES.LEGAL_VERIFICATION]: TERMINATION_STAGES.DD_LEAD_REVIEW,
                [TERMINATION_STAGES.DD_HEAD_REVIEW]: TERMINATION_STAGES.LEGAL_VERIFICATION,
                [TERMINATION_STAGES.NBH_EVALUATION]: TERMINATION_STAGES.DD_LEAD_REVIEW,
                [TERMINATION_STAGES.SCN_ISSUED]: TERMINATION_STAGES.NBH_EVALUATION,
                [TERMINATION_STAGES.PERSONAL_HEARING]: TERMINATION_STAGES.SCN_ISSUED,
                [TERMINATION_STAGES.NBH_FINAL_APPROVAL]: TERMINATION_STAGES.PERSONAL_HEARING,
                [TERMINATION_STAGES.CCO_APPROVAL]: TERMINATION_STAGES.NBH_FINAL_APPROVAL,
                [TERMINATION_STAGES.CEO_APPROVAL]: TERMINATION_STAGES.CCO_APPROVAL,
                [TERMINATION_STAGES.LEGAL_LETTER]: TERMINATION_STAGES.CEO_APPROVAL,
                [TERMINATION_STAGES.TERMINATED]: TERMINATION_STAGES.LEGAL_LETTER
            };
            return flow[currentStage] || null;
        }

        case REQUEST_TYPES.RESIGNATION: {
            const flow: Record<string, string> = {
                [RESIGNATION_STAGES.RBM]: RESIGNATION_STAGES.ASM,
                [RESIGNATION_STAGES.ZBH]: RESIGNATION_STAGES.RBM,
                [RESIGNATION_STAGES.DD_LEAD]: RESIGNATION_STAGES.ZBH,
                [RESIGNATION_STAGES.DD_HEAD]: RESIGNATION_STAGES.DD_LEAD,
                [RESIGNATION_STAGES.NBH]: RESIGNATION_STAGES.DD_HEAD,
                [RESIGNATION_STAGES.LEGAL]: RESIGNATION_STAGES.NBH,
                [RESIGNATION_STAGES.DD_ADMIN]: RESIGNATION_STAGES.LEGAL,
                [RESIGNATION_STAGES.AWAITING_FNF]: RESIGNATION_STAGES.DD_ADMIN,
                [RESIGNATION_STAGES.FNF_INITIATED]: RESIGNATION_STAGES.AWAITING_FNF,
                [RESIGNATION_STAGES.COMPLETED]: RESIGNATION_STAGES.FNF_INITIATED
            };
            return flow[currentStage] || null;
        }

        case REQUEST_TYPES.CONSTITUTIONAL: {
            const flow: Record<string, string> = {
                [CONSTITUTIONAL_STAGES.ZM_RBM_REVIEW]: CONSTITUTIONAL_STAGES.ASM_REVIEW,

                [CONSTITUTIONAL_STAGES.ZBH_REVIEW]: CONSTITUTIONAL_STAGES.ZM_RBM_REVIEW,
                [CONSTITUTIONAL_STAGES.LEAD_REVIEW]: CONSTITUTIONAL_STAGES.ZBH_REVIEW,
                [CONSTITUTIONAL_STAGES.HEAD_REVIEW]: CONSTITUTIONAL_STAGES.LEAD_REVIEW,
                [CONSTITUTIONAL_STAGES.NBH_APPROVAL]: CONSTITUTIONAL_STAGES.HEAD_REVIEW,
                [CONSTITUTIONAL_STAGES.LEGAL_REVIEW]: CONSTITUTIONAL_STAGES.NBH_APPROVAL,
                [CONSTITUTIONAL_STAGES.COMPLETED]: CONSTITUTIONAL_STAGES.LEGAL_REVIEW
            };
            return flow[currentStage] || null;
        }

        case REQUEST_TYPES.RELOCATION: {
            const flow: Record<string, string> = {
                [RELOCATION_STAGES.RBM_REVIEW]: RELOCATION_STAGES.ASM_REVIEW,
                [RELOCATION_STAGES.DD_ZM_REVIEW]: RELOCATION_STAGES.RBM_REVIEW,
                [RELOCATION_STAGES.ZBH_REVIEW]: RELOCATION_STAGES.DD_ZM_REVIEW,
                [RELOCATION_STAGES.DD_LEAD_REVIEW]: RELOCATION_STAGES.ZBH_REVIEW,
                [RELOCATION_STAGES.NBH_APPROVAL]: RELOCATION_STAGES.DD_LEAD_REVIEW,
                [RELOCATION_STAGES.LEGAL_CLEARANCE]: RELOCATION_STAGES.NBH_APPROVAL,
                [RELOCATION_STAGES.COMPLETED]: RELOCATION_STAGES.LEGAL_CLEARANCE
            };
            return flow[currentStage] || null;
        }

        default:
            return null;
    }
};

/**
 * Validates the common offboarding action payload.
 * Standardizes the mandatory remarks check for Send Back and Revoke actions.
 */
export const validateOffboardingAction = (action: string, remarks: string): { valid: boolean; message?: string } => {
    const actionLower = action.toLowerCase();
    const isSendBack = actionLower === OFFBOARDING_ACTIONS.SEND_BACK.toLowerCase() || actionLower.includes('send') && actionLower.includes('back');
    const isRevoke = actionLower === OFFBOARDING_ACTIONS.REVOKE.toLowerCase();

    if ((isSendBack || isRevoke) && (!remarks || remarks.trim().length < 5)) {
        return {
            valid: false,
            message: `Mandatory remarks (min 5 characters) required for ${isSendBack ? 'Send Back' : 'Revoke'} action.`
        };
    }

    return { valid: true };
};

/**
 * Maps offboarding action to system AUDIT_ACTIONS
 */
export const getOffboardingAuditAction = (action: string, requestType: string): string => {
    const actionLower = action.toLowerCase();
    
    // 1. Direct intent mapping (Deterministic)
    if (actionLower === OFFBOARDING_ACTIONS.REJECT.toLowerCase()) return AUDIT_ACTIONS.REJECTED;
    if (actionLower === OFFBOARDING_ACTIONS.APPROVE.toLowerCase()) return AUDIT_ACTIONS.APPROVED;
    if (actionLower === OFFBOARDING_ACTIONS.REVOKE.toLowerCase()) {
        switch (requestType) {
            case REQUEST_TYPES.RESIGNATION: return AUDIT_ACTIONS.RESIGNATION_REVOKED;
            case REQUEST_TYPES.TERMINATION: return AUDIT_ACTIONS.TERMINATION_REVOKED;
            case REQUEST_TYPES.RELOCATION: return AUDIT_ACTIONS.RELOCATION_REVOKED;
            case REQUEST_TYPES.CONSTITUTIONAL: return AUDIT_ACTIONS.CONSTITUTIONAL_REVOKED;
            default: return AUDIT_ACTIONS.UPDATED;
        }
    }
    if (actionLower === OFFBOARDING_ACTIONS.SEND_BACK.toLowerCase() || actionLower === OFFBOARDING_ACTIONS.RECONSIDER.toLowerCase()) {
        switch (requestType) {
            case REQUEST_TYPES.RESIGNATION: return AUDIT_ACTIONS.RESIGNATION_SENT_BACK;
            case REQUEST_TYPES.TERMINATION: return AUDIT_ACTIONS.TERMINATION_SENT_BACK;
            case REQUEST_TYPES.RELOCATION: return AUDIT_ACTIONS.RELOCATION_SENT_BACK;
            case REQUEST_TYPES.CONSTITUTIONAL: return AUDIT_ACTIONS.CONSTITUTIONAL_SENT_BACK;
            default: return AUDIT_ACTIONS.UPDATED;
        }
    }

    // 2. Fallback to descriptive scanning (Legacy/Edge cases)
    if (actionLower.includes('reject')) return AUDIT_ACTIONS.REJECTED;
    if (actionLower.includes('revok')) {
        switch (requestType) {
            case REQUEST_TYPES.TERMINATION: return AUDIT_ACTIONS.TERMINATION_REVOKED;
            default: return AUDIT_ACTIONS.UPDATED;
        }
    }
    if (actionLower.includes('send back') || actionLower.includes('sent back') || actionLower.includes('reconsider')) {
        switch (requestType) {
            case REQUEST_TYPES.TERMINATION: return AUDIT_ACTIONS.TERMINATION_SENT_BACK;
            default: return AUDIT_ACTIONS.UPDATED;
        }
    }

    return (actionLower.includes('approval') || actionLower.includes('approve')) ? AUDIT_ACTIONS.APPROVED : AUDIT_ACTIONS.UPDATED;
};

/**
 * Formats offboarding actions and stages for user-friendly display (Title Case).
 * Replaces underscores/hyphens with spaces and preserves specific abbreviations.
 */
export const formatOffboardingAction = (label: string): string => {
    if (!label) return '';
    
    // 1. Clean up separators and normalize case
    let formatted = label.replace(/[_-]/g, ' ').toLowerCase();

    // 2. Identify tokens and preserve known abbreviations
    const abbreviations = ['CCO', 'NBH', 'CEO', 'RBM', 'ZBH', 'ASM', 'LOA', 'SCN', 'DD', 'ZM', 'FNF'];
    
    return formatted.split(' ').map(word => {
        const upperWord = word.toUpperCase();
        if (abbreviations.includes(upperWord)) return upperWord;
        
        // Capitalize first letter
        return word.charAt(0).toUpperCase() + word.slice(1);
    }).join(' ');
};
