const SocketIO = require('socket.io') 
let io

const onSocketHandshakeAuthVerifier = (socket, next) => {

    console.log(`${new Date().toISOString()} ===========> MIDDLEWARE: Socket trying to connect with data ${JSON.stringify(socket.handshake.auth)} and origin ${socket.handshake.headers.origin}`)
    const codWeb = socket.handshake.auth.codWeb
    const extension = socket.handshake.auth.extension
    const origin = socket.handshake.headers.origin
    if (!origin) {
        console.log(`${new Date().toISOString()} ===========> MIDDLEWARE: Socket with data ${JSON.stringify(socket.handshake.auth)} disconnected because didn't send the origin`)
        return next(new Error(`Invalid handshake header information information origin must be specified`))
    }
    const isFromHitphoneWebClient = origin.includes(process.env.URL_HITPHONE_FRONTEND)
    if (!isFromHitphoneWebClient) {
        socket.data.isFromHitphoneWebClient = false
        return next()
    }
    
    if (!codWeb || !extension) { 
        console.log(`${new Date().toISOString()} ===========> MIDDLEWARE: Socket with data ${JSON.stringify(socket.handshake.auth)} disconnected because didn't send extension or codWeb`)
        return next(new Error(`Invalid handshake auth information, required attributes codWeb, extension`))
    }

    socket.data.codWeb = codWeb
    socket.data.extension = extension
    socket.data.isFromHitphoneWebClient = true
    return next()
}

const onConnectionHitphoneWebClient = (socket) => {
    const { isFromHitphoneWebClient } = socket.data
    if (!isFromHitphoneWebClient) return

    console.log(`${new Date().toISOString()} ===========> SOCKET CONNECTION: Client connected from "Hitphone WEB Client"`)
    const { codWeb, extension } = socket.data
    socket.join(`${codWeb}@${extension}`)

    socket.on("disconnect", (data) => {
        console.log(`${new Date().toISOString()} ==========> SOCKET DISCONNECT: "Hitphone WEB Client" Client disconnected socket: ${data}`)
    }) 
}

const onConnectionCrmWizardClient = (socket) => {
    const { isFromHitphoneWebClient } = socket.data
    if (isFromHitphoneWebClient) return
    
    console.log(`${new Date().toISOString()} ===========> SOCKET CONNECTION: Client connected from "CRM Wizard client"`)
    const { codWeb, extension } = socket.data
    socket.join(`${codWeb}@${extension}`)

    socket.on("disconnect", (data) => {
        console.log(`${new Date().toISOString()} ==========> SOCKET DISCONNECT: "CRM Wizard client" Client disconnected, data: ${data}`)
    }) 
}

const initIO = (httpServer) => {
    const IS_DEV = process.env.IS_DEV ? Boolean(process.env.IS_DEV) : false

    io = SocketIO(httpServer, {
        cors: {
            origin: IS_DEV ? "*" : [process.env.URL_OAUTH_FRONTEND_SUCCESS_REDIRECT, process.env.URL_HITPHONE_FRONTEND]
        },
        maxHttpBufferSize: 1e8
    })

    io.use(onSocketHandshakeAuthVerifier)
    /**
     * CRM Wizard Client
     */
    io.on("connection", onConnectionCrmWizardClient)
    /**
     * Hitphone Client Flow
     */
    io.on("connection", onConnectionHitphoneWebClient)
    
    return io
}

const getIO = () => {
    if (!io) {
        throw new AppError("Socket IO not initialized")
    }
    return io
}

module.exports = { initIO, getIO }