"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getIO = exports.initIO = void 0;
const socket_io_1 = require("socket.io");
const AppError_1 = __importDefault(require("../errors/AppError"));
const logger_1 = require("../utils/logger");
const redis_adapter_1 = require("@socket.io/redis-adapter");
const redis_1 = require("redis");
const uuid_1 = require("uuid");
let io;
const SplitDateTime_1 = require("../helpers/SplitDateTime");
const format_1 = __importDefault(require("date-fns/format"));
const pt_BR_1 = __importDefault(require("date-fns/locale/pt-BR"));
const wbotMessageListener_1 = require("../services/WbotServices/wbotMessageListener");
const Whatsapp_1 = __importDefault(require("../models/Whatsapp"));
const RedisClient_1 = require("../helpers/RedisClient");
let count = 0;
let listOnline = [];
let listOnlineAux = [];
let countOnline = 0;
let obj = { listOnline: [], uuid: null, listOnlineAux: [] };
let lstOnline = [];
let lstOnlineAux = [];
let lstTry = [];
let dateTime = SplitDateTime_1.splitDateTime(new Date(format_1.default(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: pt_BR_1.default })));
const pubClient = redis_1.createClient({ url: 'redis://172.31.187.29:6379' });
const subClient = pubClient.duplicate();
pubClient.connect().catch(console.error);
subClient.connect().catch(console.error);
const initIO = (httpServer) => {
    io = new socket_io_1.Server(httpServer, {
        path: "/api-ws/socketio",
        wsEngine: require("eiows").Server,
        cors: {
            origin: "http://172.31.187.38:3331",
            methods: ["GET", "POST"],
            allowedHeaders: ["my-custom-header"],
            credentials: true
        },
        //  transports:['websocket', 'polling'],
        maxHttpBufferSize: 1e8,
        pingInterval: 25000,
        pingTimeout: 60000,
        adapter: redis_adapter_1.createAdapter(pubClient, subClient)
    });
    io.on("connection", socket => {
        logger_1.logger.info("Client Connected");
        socket.on("joinWhatsSession", (whatsappId) => {
            logger_1.logger.info(`A client joined a joinWhatsSession channel: ${whatsappId}`);
            socket.join(`session_${whatsappId}`);
        });
        socket.on("message_from_client", () => {
            socket.emit("message_from_server", "Sent an event from the server!");
        });
        socket.on("message_create", (data) => __awaiter(void 0, void 0, void 0, function* () {
            wbotMessageListener_1.handleMessage(data.msg, data);
        }));
        socket.on("media_uploaded", (data) => __awaiter(void 0, void 0, void 0, function* () {
            wbotMessageListener_1.handleMessage(data.msg, data);
        }));
        socket.on("message_ack", (data) => __awaiter(void 0, void 0, void 0, function* () {
            wbotMessageListener_1.handleMsgAck(data.id, data.ack);
        }));
        socket.on("campaign_message_sent", (data) => __awaiter(void 0, void 0, void 0, function* () {
            // console.log("campaign_message_sent: ", data);
            const io = exports.getIO();
            let campaign = {};
            if (data === null || data === void 0 ? void 0 : data.read) {
                campaign = {
                    id: data.id,
                    read: data.read
                };
            }
            else if (data === null || data === void 0 ? void 0 : data.sent) {
                campaign = {
                    id: data.id,
                    sent: data.sent
                };
            }
            else if (data === null || data === void 0 ? void 0 : data.status) {
                campaign = {
                    id: data.id,
                    status: data.status
                };
            }
            io.emit("campaign", {
                action: "update",
                campaign
            });
        }));
        socket.on("online", (userId) => {
            // console.log('userId: ', userId)
            return;
            obj.uuid = uuid_1.v4();
            if (userId.logoutUserId) {
                let index = lstOnline.findIndex((x) => x.id == userId.logoutUserId);
                if (index != -1) {
                    lstOnline.splice(index, 1);
                }
                index = lstOnlineAux.findIndex((x) => x.id == userId.logoutUserId);
                if (index != -1) {
                    lstOnlineAux.splice(index, 1);
                }
                return;
            }
            if (lstOnline.length == 0) {
                const index = listOnlineAux.findIndex((e) => e.id == userId);
                if (index == -1) {
                    listOnlineAux.push({ id: userId });
                }
                else {
                    return;
                }
                lstOnline.push({ id: userId, status: "online", try: 0 });
                lstOnlineAux.push({ id: userId });
                console.log(" 1 - PUSHED NEW USER ID 1: ", userId);
                obj.listOnline = lstOnline;
            }
            else {
                const indexAux = lstOnlineAux.findIndex((e) => e.id == userId);
                if (indexAux == -1) {
                    lstOnlineAux.push({ id: userId });
                }
                const index = lstOnline.findIndex((e) => e.id == userId);
                if (index == -1) {
                    lstOnline.push({ id: userId, status: "online", try: 0 });
                    console.log("  2 - PUSHED NEW USER ID: ", userId);
                    obj.listOnline = lstOnline;
                }
                else {
                    if (countOnline > lstOnline.length - 1) {
                        lstOnline.forEach((x) => {
                            if (lstOnlineAux.map((e) => e.id).includes(x.id)) {
                                x.try = 0;
                                x.status = "online";
                            }
                        });
                        var difference = lstOnline.filter((x) => !lstOnlineAux.map((e) => e.id).includes(x.id));
                        if (difference.length > 0) {
                            difference.forEach(e => {
                                e.try += 1;
                                if (e.try > 1) {
                                    e.status = "waiting...";
                                }
                                if (e.try > 3) {
                                    const index = lstOnline.findIndex((x) => x.id == e.id);
                                    if (index != -1) {
                                        lstOnline.splice(index, 1);
                                    }
                                }
                            });
                        }
                        obj.listOnline = lstOnline;
                        obj.listOnlineAux = lstOnlineAux;
                        lstOnlineAux = [];
                        listOnlineAux = [];
                        countOnline = -1;
                    }
                    countOnline++;
                }
            }
            exports.ob = obj;
        });
        socket.on("joinChatBox", (ticketId) => {
            logger_1.logger.info("A client joined a ticket channel");
            socket.join(ticketId);
        });
        socket.on("joinChatBox", (ticketId) => {
            console.log(`--> joinChatBox - ticketId: ${ticketId} - type: ${typeof ticketId}`);
            console.log("A client joined a ticket channel");
            logger_1.logger.info("A client joined a ticket channel");
            socket.join(ticketId);
        });
        socket.on("leaveChatBox", (ticketId) => {
            console.log(`--> leaveChatBox - ticketId: ${ticketId} - type: ${typeof ticketId}`);
            logger_1.logger.info("A client left a ticket channel");
            console.log(`Client will leave ChatBox ${[...socket.rooms]}`);
            socket.leave(ticketId);
            console.log(`Client left ChatBox ${[...socket.rooms]}`);
        });
        socket.on("joinNotification", () => {
            logger_1.logger.info("A client joined notification channel");
            socket.join("notification");
        });
        socket.on("joinTickets", (status) => {
            logger_1.logger.info(`A client joined to ${status} tickets channel.`);
            socket.join(status);
        });
        socket.on("disconnect", (data) => {
            logger_1.logger.info(`Client disconnected socket: ${data}`);
        });
        socket.on("disconnecting", () => __awaiter(void 0, void 0, void 0, function* () {
            console.log("socket.rooms: ", socket.rooms); // the Set contains at least the socket ID
            let rooms = socket.rooms;
            console.log("rooms: ", rooms, " | rooms.size: ", rooms.size);
            if (rooms && rooms.size == 1)
                return;
            if (rooms && rooms.size == 2 && ![...rooms][1].startsWith("session_"))
                return;
            let whatsappIds = yield RedisClient_1.get({
                key: "whatsapp:*",
                parse: true
            });
            // let whatsappIds: any = await Whatsapp.findAll({
            //   attributes: ["id"],
            //   raw: true
            // });
            if (whatsappIds && whatsappIds.length > 0) {
                // whatsappIds = whatsappIds.map((e: any) => `${e.id}`);
                console.log("whatsappIds whatsappIds whatsappIds whatsappIds whatsappIds: ", whatsappIds);
                if (rooms &&
                    rooms.size == 2 &&
                    [...rooms][1].startsWith("session_") &&
                    whatsappIds.includes([...rooms][1].replace("session_", ""))) {
                    console.log([...rooms][1]);
                    let whatsappId = [...rooms][1].replace("session_", "");
                    const whatsapp = yield Whatsapp_1.default.findByPk(whatsappId, {});
                    if (whatsapp) {
                        yield whatsapp.update({ status: "OPENING" });
                        io.emit("whatsappSession", {
                            action: "update",
                            session: whatsapp
                        });
                    }
                }
            }
        }));
    });
    return io;
};
exports.initIO = initIO;
const getIO = () => {
    if (!io) {
        throw new AppError_1.default("Socket IO not initialized");
    }
    return io;
};
exports.getIO = getIO;
function writeFileAsync(arg0, data, arg2) {
    throw new Error("Function not implemented.");
}
// exports.listOnlineUsers = listUserId
// exports.listUserId
