import {injectEvent} from '../../core/injector'
import {ContentBlock} from '../Navigation/typings'
import {
    BreakProperties,
    CallCenterEventType, ContactProperties, OpsScorecardProperties,
} from './typings'
import CallCenterPropertiesTI from './typings-ti'
import CfExceptionHandler from "../../core/CfExceptionHandler";
import {isISOLocal} from "../../utils";


const logIngestEvent = async (eventType: CallCenterEventType,
                              properties: BreakProperties | ContactProperties | OpsScorecardProperties,
                              sendNow = false) => {

    let checkProps: BreakProperties | ContactProperties | OpsScorecardProperties | null = null;

    switch (eventType) {
        case CallCenterEventType.Break:
            checkProps = validateBreakEvent(properties as BreakProperties);
            break;
        case CallCenterEventType.Contact:
            checkProps = validateContactEvent(properties as ContactProperties);
            break;
        case CallCenterEventType.OpsScorecard:
            checkProps = validateOpsScorecardEvent(properties as OpsScorecardProperties);
            break;
        default:
            return; // Exit early if eventType is unrecognized
    }

    if (!checkProps) {
        return; // Exit if the properties validation failed
    }

    injectEvent(
        properties,
        [CallCenterPropertiesTI],
        eventType,
        ContentBlock.CallCenter,
        '',
        sendNow
    )
}

const validateBreakEvent = (properties: BreakProperties) => {
    if(properties.type == undefined){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Break, 'invalid break type')
    }else if(properties.action == undefined){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Break, 'invalid break action')
    }else if(properties.total_time < 0){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Break, 'invalid break total_time')
    }else if(properties.consumed_time < 0){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Break, 'invalid break consumed_time')
    }
    return properties
}

const validateContactEvent = (properties: ContactProperties) => {
    if(properties.action == undefined){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact action')
    }else if(properties.details == undefined){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact details')
    }else if(!properties.details.id){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact details id')
    }else if(!properties.details.channel){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact details channel')
    }else if(!properties.details.type){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact details type')
    }else if(properties.details.start_time && !isISOLocal(properties.details.start_time)){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact start_time: should be in ISO8601 format e.g. 2025-01-01T12:00:27.87+02:00')
    }else if(properties.transfer && !properties.transfer.id){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.Contact, 'invalid contact transfer id')
    }
    return properties
}

const validateOpsScorecardEvent = (properties: OpsScorecardProperties) => {
    if(properties.quality_traits == undefined){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.OpsScorecard, 'invalid quality_traits')
    }else if(properties.quality_traits.audit_count == undefined){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.OpsScorecard, 'invalid quality_traits audit_count')
    }else if(!properties.quality_traits.performance_group){
        new CfExceptionHandler().throwAndLogError(CallCenterEventType.OpsScorecard, 'invalid quality_traits performance_group')
    }
    return properties
}

export default {
    logIngestEvent
}
