"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.remove = exports.update = exports.count = exports.show = exports.store = exports.remoteTicketCreation = exports.index = void 0;
const socket_1 = require("../libs/socket");
const CreateTicketService_1 = __importDefault(require("../services/TicketServices/CreateTicketService"));
const DeleteTicketService_1 = __importDefault(require("../services/TicketServices/DeleteTicketService"));
const ListTicketsService_1 = __importDefault(require("../services/TicketServices/ListTicketsService"));
const ShowTicketService_1 = __importDefault(require("../services/TicketServices/ShowTicketService"));
const UpdateTicketService_1 = __importDefault(require("../services/TicketServices/UpdateTicketService"));
const SendWhatsAppMessage_1 = __importDefault(require("../services/WbotServices/SendWhatsAppMessage"));
const ShowWhatsAppService_1 = __importDefault(require("../services/WhatsappService/ShowWhatsAppService"));
const ShowStatusChatEndService_1 = __importDefault(require("../services/StatusChatEndService/ShowStatusChatEndService"));
const CreateSchedulingNotifyService_1 = __importDefault(require("../services/SchedulingNotifyServices/CreateSchedulingNotifyService"));
const ListSchedulingNotifyContactService_1 = __importDefault(require("../services/SchedulingNotifyServices/ListSchedulingNotifyContactService"));
const CheckSchedulingReminderNotify_1 = require("../helpers/CheckSchedulingReminderNotify");
const pt_BR_1 = __importDefault(require("date-fns/locale/pt-BR"));
const SplitDateTime_1 = require("../helpers/SplitDateTime");
const format_1 = __importDefault(require("date-fns/format"));
const sequelize_1 = require("sequelize");
const ListStatusChatEndService_1 = __importDefault(require("../services/StatusChatEndService/ListStatusChatEndService"));
const Ticket_1 = __importDefault(require("../models/Ticket"));
const OnlineReporEmiterInfoByUser_1 = __importDefault(require("../helpers/OnlineReporEmiterInfoByUser"));
const CountTicketService_1 = __importDefault(require("../services/TicketServices/CountTicketService"));
const Contact_1 = __importDefault(require("../models/Contact"));
const BotIsOnQueue_1 = __importDefault(require("../helpers/BotIsOnQueue"));
const SetMessageAsRead_1 = require("../helpers/SetMessageAsRead");
const WhaticketSettings_1 = require("../helpers/WhaticketSettings");
const ListWhatsAppsForQueueService_1 = __importDefault(require("../services/WhatsappService/ListWhatsAppsForQueueService"));
const ListWhatsAppsNumber_1 = __importDefault(require("../services/WhatsappService/ListWhatsAppsNumber"));
const Whatsapp_1 = __importDefault(require("../models/Whatsapp"));
const AppError_1 = __importDefault(require("../errors/AppError"));
const FindOrCreateTicketService_1 = __importDefault(require("../services/TicketServices/FindOrCreateTicketService"));
const CreateContactService_1 = __importDefault(require("../services/ContactServices/CreateContactService"));
const RedisClient_1 = require("../helpers/RedisClient");
const Queue_1 = __importDefault(require("../models/Queue"));
const controllByNumber_1 = __importDefault(require("../helpers/controllByNumber"));
const index = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const { pageNumber, status, date, searchParam, showAll, queueIds: queueIdsStringified, withUnreadMessages, unlimited, searchParamContent } = req.query;
    const userId = req.user.id;
    let queueIds = [];
    if (queueIdsStringified && queueIdsStringified.trim().length > 0) {
        queueIds = JSON.parse(queueIdsStringified);
    }
    const { tickets, count, hasMore, remoteTicketsControll } = yield ListTicketsService_1.default({
        searchParam,
        pageNumber,
        status,
        date,
        showAll,
        userId,
        queueIds,
        withUnreadMessages,
        unlimited,
        searchParamContent
    });
    return res
        .status(200)
        .json({ tickets, count, hasMore, remoteTicketsControll });
});
exports.index = index;
const remoteTicketCreation = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    var _a;
    let { queueId, contact_from, cc, contact_to, msg, contact_name } = req.body;
    let whatsappId;
    if (!queueId && !contact_from && !cc) {
        return res.status(400).json({
            error: `Property 'queueId' or 'contact_from' or 'cc' is required.`
        });
    }
    const validate = ["contact_to", "msg"];
    const validateOnlyNumber = ["queueId", "contact_to", "contact_from"];
    for (let prop of validate) {
        if (!req.body[prop])
            return res
                .status(400)
                .json({ error: `Property '${prop}' is undefined.` });
        if (validateOnlyNumber.includes(prop)) {
            if (!/^\d+$/.test(req.body[prop])) {
                return res
                    .status(400)
                    .json({ error: `The property '${prop}' must be a number` });
            }
        }
    }
    if (queueId) {
        const whatsapps = yield ListWhatsAppsForQueueService_1.default(queueId, "CONNECTED");
        if (!whatsapps || (whatsapps === null || whatsapps === void 0 ? void 0 : whatsapps.length) == 0) {
            return res.status(500).json({
                msg: `queueId ${queueId} does not have a WhatsApp number associated with it or the number's session is disconnected.`
            });
        }
        const { id } = whatsapps[0];
        whatsappId = id;
    }
    else if (contact_from) {
        const whatsapp = yield Whatsapp_1.default.findOne({
            where: { number: contact_from, status: "CONNECTED" }
        });
        if (!whatsapp) {
            return res.status(404).json({
                msg: `Whatsapp number ${contact_from} not found or disconnected!`
            });
        }
        const { id } = whatsapp;
        const { queues } = yield ShowWhatsAppService_1.default(id);
        if (!queues || queues.length == 0) {
            return res.status(500).json({
                msg: `The WhatsApp number ${contact_from} is not associated with any queue! `
            });
        }
        queueId = queues[0].id;
        whatsappId = id;
    }
    else if (cc) {
        const queue = yield Queue_1.default.findOne({ where: { cc } });
        if (!queue) {
            return res.status(404).json({
                msg: `Queue with cc ${cc} not found! `
            });
        }
        queueId = queue.id;
        const whatsapps = yield ListWhatsAppsForQueueService_1.default(queueId, "CONNECTED");
        if (whatsapps.length === 0) {
            return res.status(500).json({
                msg: `No WhatsApp found for this cc ${cc} or the WhatsApp number is disconnected! `
            });
        }
        whatsappId = whatsapps[0].id;
    }
    // const validNumber = await CheckIsValidContact(contact_to, true);
    const validNumber = contact_to;
    if (validNumber) {
        let contact = yield Contact_1.default.findOne({ where: { number: validNumber } });
        if (!contact) {
            // const profilePicUrl = await GetProfilePicUrl(validNumber);
            contact = yield CreateContactService_1.default({
                name: contact_name ? contact_name : contact_to,
                number: validNumber
                // profilePicUrl
            });
            const io = socket_1.getIO();
            io.emit("contact", {
                action: "create",
                contact
            });
        }
        const { id: contactId } = contact;
        const botInfo = yield BotIsOnQueue_1.default("botqueue");
        // ticket from queueChoice or bot
        let ticket = yield Ticket_1.default.findOne({
            where: {
                [sequelize_1.Op.or]: [
                    { contactId, status: "queueChoice" },
                    { contactId, status: "open", userId: botInfo.userIdBot }
                ]
            }
        });
        if (((_a = WhaticketSettings_1.getSettingValue("whatsaAppCloudApi")) === null || _a === void 0 ? void 0 : _a.value) == "enabled") {
            if (ticket) {
                yield UpdateTicketService_1.default({
                    ticketData: { status: "closed" },
                    ticketId: ticket.id
                });
                ticket = null;
            }
        }
        else {
            if (ticket) {
                yield UpdateTicketService_1.default({
                    ticketData: { status: "closed" },
                    ticketId: ticket.id
                });
            }
        }
        ticket = yield Ticket_1.default.findOne({
            where: {
                [sequelize_1.Op.or]: [
                    { contactId, status: "pending" },
                    { contactId, status: "open" }
                ]
            }
        });
        if (ticket) {
            console.log(`THE CAMPAIGN TICKET WAS NOT CREATED BECAUSE THE TICKET IS PENDING OR OPEN`);
            return res.status(422).json({
                msg: `The campaign ticket was not created because the number ${contact_to} already has a ticket open or pending`
            });
        }
        ticket = yield FindOrCreateTicketService_1.default(contact, whatsappId, 0, undefined, queueId, true);
        // botSendMessage(ticket, `${msg}`);
        yield ticket.update({
            lastMessage: msg
        });
        yield RedisClient_1.set(`remote:ticketId:${ticket.id}`, JSON.stringify({
            id: ticket.id,
            createdAt: ticket.createdAt,
            updatedAt: ticket.updatedAt,
            whatsappId: ticket.whatsappId,
            status: ticket.status
        }));
        const io = socket_1.getIO();
        io.to(ticket.status).emit("ticket", {
            action: "update",
            ticket
        });
        const obj = yield controllByNumber_1.default();
        if (obj === null || obj === void 0 ? void 0 : obj.tickets) {
            io.emit("remoteTickesControll", {
                action: "update",
                tickets: obj.ticketIds
            });
        }
        console.log(`REMOTE TICKET CREATION FROM ENDPOINT | STATUS: 200 | MSG: success`);
        return res.status(200).json({ msg: "success" });
    }
    console.log(`REMOTE TICKET CREATION FROM ENDPOINT | STATUS: 500 | MSG: The number ${contact_to} does not exist on WhatsApp`);
    return res
        .status(500)
        .json({ msg: `The number ${contact_to} does not exist on WhatsApp` });
});
exports.remoteTicketCreation = remoteTicketCreation;
const store = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    var _b;
    const { contactId, status, userId, msg, queueId, whatsappId } = req.body;
    const botInfo = yield BotIsOnQueue_1.default("botqueue");
    let ticket = yield Ticket_1.default.findOne({
        where: {
            [sequelize_1.Op.or]: [
                { contactId, status: "queueChoice" },
                { contactId, status: "open", userId: botInfo.userIdBot }
            ]
        }
    });
    if (((_b = WhaticketSettings_1.getSettingValue("whatsaAppCloudApi")) === null || _b === void 0 ? void 0 : _b.value) == "enabled") {
        if (ticket) {
            yield UpdateTicketService_1.default({
                ticketData: { status: "closed" },
                ticketId: ticket.id
            });
            ticket = null;
        }
    }
    else {
        if (ticket) {
            yield UpdateTicketService_1.default({
                ticketData: { status: "open", userId: userId, queueId },
                ticketId: ticket.id
            });
        }
    }
    if (!ticket) {
        ticket = yield CreateTicketService_1.default({
            contactId,
            status,
            userId,
            queueId,
            whatsappId
        });
    }
    const io = socket_1.getIO();
    io.to(ticket.status).emit("ticket", {
        action: "update",
        ticket
    });
    return res.status(200).json(ticket);
});
exports.store = store;
const show = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const { ticketId } = req.params;
    const contact = yield ShowTicketService_1.default(ticketId);
    const { statusChatEnd, count, hasMore } = yield ListStatusChatEndService_1.default({
        searchParam: "",
        pageNumber: "1"
    });
    //////////////////
    const schedulesContact = yield ListSchedulingNotifyContactService_1.default(contact.contact.number);
    /////////////////
    return res.status(200).json({ contact, statusChatEnd, schedulesContact });
});
exports.show = show;
const count = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    // type indexQ = { status: string; date?: string; };
    const { status, date, queueIds } = req.query;
    const ticketCount = yield CountTicketService_1.default(status, date, queueIds);
    return res.status(200).json(ticketCount);
});
exports.count = count;
const update = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    var _c, _d, _e, _f, _g, _h, _j, _k;
    console.log("ENTROU NO UPDATE TICKET CONTROLLER");
    const { ticketId } = req.params;
    const userOldInfo = yield Ticket_1.default.findByPk(ticketId);
    let ticket2 = {};
    if (req.body["status"] === "closed") {
        const { status, userId, schedulingNotifyData } = req.body;
        // lembrete
        const scheduleData = JSON.parse(schedulingNotifyData);
        console.log("scheduleData: ", scheduleData);
        const statusChatEnd = yield ShowStatusChatEndService_1.default({
            name: scheduleData.statusChatEndName
        });
        const { ticket } = yield UpdateTicketService_1.default({
            ticketData: {
                status: status,
                userId: userId,
                statusChatEnd: statusChatEnd.name,
                statusChatEndId: statusChatEnd.id
            },
            ticketId
        });
        let _farewellMessage;
        if (((_c = WhaticketSettings_1.getSettingValue("farewellMessageByStatusChatEnd")) === null || _c === void 0 ? void 0 : _c.value) == "enabled") {
            const statusChatEndData = yield RedisClient_1.get({
                key: `statusChatEnd:${statusChatEnd.id}`,
                parse: true
            });
            if (statusChatEndData && (statusChatEndData === null || statusChatEndData === void 0 ? void 0 : statusChatEndData.farewellMessage) &&
                ((_e = (_d = statusChatEndData === null || statusChatEndData === void 0 ? void 0 : statusChatEndData.farewellMessage) === null || _d === void 0 ? void 0 : _d.trim()) === null || _e === void 0 ? void 0 : _e.length) > 0) {
                const { farewellMessage } = statusChatEndData;
                _farewellMessage = farewellMessage;
            }
        }
        else if (((_f = WhaticketSettings_1.getSettingValue("farewellMessageByQueue")) === null || _f === void 0 ? void 0 : _f.value) == "enabled") {
            const queueData = yield RedisClient_1.get({
                key: `queue:${ticket.queueId}`,
                parse: true
            });
            if (queueData && (queueData === null || queueData === void 0 ? void 0 : queueData.farewellMessage) &&
                ((_h = (_g = queueData === null || queueData === void 0 ? void 0 : queueData.farewellMessage) === null || _g === void 0 ? void 0 : _g.trim()) === null || _h === void 0 ? void 0 : _h.length) > 0) {
                const { farewellMessage } = queueData;
                _farewellMessage = farewellMessage;
            }
        }
        else if (scheduleData.farewellMessage) {
            const whatsapp = yield ShowWhatsAppService_1.default(ticket.whatsappId);
            const { farewellMessage } = whatsapp;
            if (farewellMessage) {
                _farewellMessage = farewellMessage;
            }
        }
        if (_farewellMessage) {
            yield SendWhatsAppMessage_1.default({ body: `\u200e${_farewellMessage}`, ticket });
        }
        console.log("tatusChatEnd.name: ", statusChatEnd.name);
        if (statusChatEnd.name === "LEMBRETE" ||
            statusChatEnd.name === "AGENDAMENTO À CONFIRMAR") {
            //  lembrete                              // agendamento
            if (CheckSchedulingReminderNotify_1.isScheduling(scheduleData.schedulingDate, scheduleData.schedulingTime)) {
                console.log("*** É AGENDAMENTO!");
            }
            else {
                console.log("*** É LEMBRETE!");
            }
            const schedulingNotifyCreate = yield CreateSchedulingNotifyService_1.default({
                ticketId: scheduleData.ticketId,
                statusChatEndId: `${statusChatEnd.id}`,
                schedulingDate: scheduleData.schedulingDate,
                schedulingTime: scheduleData.schedulingTime,
                message: scheduleData.message
            });
        }
        ticket2 = ticket;
    }
    else {
        // Para aparecer pendente para todos usuarios que estao na fila
        if (req.body.transfer) {
            req.body.userId = null;
        }
        let ticketData = req.body;
        if (((_j = WhaticketSettings_1.getSettingValue("oneContactChatWithManyWhats")) === null || _j === void 0 ? void 0 : _j.value) == "enabled") {
            if (ticketData.transfer) {
                const whatsappsByqueue = yield ListWhatsAppsForQueueService_1.default(ticketData.queueId);
                if (userOldInfo) {
                    let listTicketOpenPending = [];
                    for (const w of whatsappsByqueue) {
                        let whats = yield ListWhatsAppsNumber_1.default(w.id);
                        const ticket = yield Ticket_1.default.findOne({
                            where: {
                                [sequelize_1.Op.and]: [
                                    { contactId: userOldInfo.contactId },
                                    {
                                        whatsappId: {
                                            [sequelize_1.Op.in]: whats.whatsapps.map((w) => w.id)
                                        }
                                    },
                                    { status: { [sequelize_1.Op.or]: ["open", "pending"] } }
                                ]
                            }
                        });
                        if (ticket) {
                            listTicketOpenPending.push({
                                ticketId: ticket.id,
                                status: ticket.status,
                                userId: ticket.userId,
                                contactId: ticket.contactId,
                                whatsappId: ticket.whatsappId,
                                queueId: ticket.queueId
                            });
                        }
                    }
                    // console.log("userOldInfo: ", JSON.stringify(userOldInfo, null, 6));
                    // console.log("##########")
                    // console.log(
                    //   "listTicketOpenPending: ",
                    //   JSON.stringify(listTicketOpenPending)
                    // );
                    if (((_k = listTicketOpenPending.filter((ob) => userOldInfo.whatsappId != ob.whatsappId)) === null || _k === void 0 ? void 0 : _k.length) > 0) {
                        throw new AppError_1.default("ERR_OTHER_OPEN_TICKET");
                    }
                }
                //////////////////////////////////////////////
                // const defaultWhatsapp: any = await GetDefaultWhatsApp({
                //   userId: ticketData.userId
                // });
                // console.log(
                //   "ticketData.userId: ",
                //   ticketData.userId,
                //   " | defaultWhatsapp: ",
                //   JSON.stringify(defaultWhatsapp, null, 6)
                // );
                // const _ticket: any = await Ticket.findByPk(ticketId);
                // if (defaultWhatsapp && ticketData.status != "open") {
                //   await CheckContactOpenTickets(
                //     _ticket.dataValues.contactId,
                //     defaultWhatsapp.dataValues.id
                //   );
                // }
                // ticketData.whatsappId = defaultWhatsapp.dataValues.id;
            }
        }
        console.log("--------> ticketData.status: ", ticketData.status, " | ticketData.fromMe: ", ticketData.fromMe);
        const { ticket } = yield UpdateTicketService_1.default({
            ticketData,
            ticketId
        });
        if (ticketData.status == "open" && !ticketData.fromMe) {
            yield SetMessageAsRead_1.setMessageAsRead(ticket);
        }
        if (ticketData.status == "open" || ticketData.status == "pending") {
            let ticketRemote = yield RedisClient_1.get({
                key: `remote:ticketId:${ticketId}`
            });
            if (ticketRemote) {
                ticketRemote = JSON.parse(ticketRemote);
                ticketRemote = Object.assign(Object.assign({}, ticketRemote), {
                    status: ticketData.status == "open" ? "open" : "pending",
                    updatedAt: ticket.updatedAt
                });
                RedisClient_1.set(`remote:ticketId:${ticketId}`, JSON.stringify(ticketRemote));
            }
        }
        if (ticketData.userId) {
            const dateToday = SplitDateTime_1.splitDateTime(new Date(format_1.default(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: pt_BR_1.default })));
            OnlineReporEmiterInfoByUser_1.default(ticketData.userId.toString(), dateToday.fullDate, dateToday.fullDate);
        }
        ticket2 = ticket;
    }
    if (userOldInfo) {
        const dateToday = SplitDateTime_1.splitDateTime(new Date(format_1.default(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: pt_BR_1.default })));
        if (userOldInfo.userId) {
            OnlineReporEmiterInfoByUser_1.default(userOldInfo.userId.toString(), dateToday.fullDate, dateToday.fullDate);
        }
    }
    return res.status(200).json(ticket2);
});
exports.update = update;
// export const update = async (
//   req: Request,
//   res: Response
// ): Promise<Response> => {
//   const { ticketId } = req.params;
//   const ticketData: TicketData = req.body;
//   const { ticket } = await UpdateTicketService({
//     ticketData,
//     ticketId
//   });
//   if (ticket.status === "closed") {
//     const whatsapp = await ShowWhatsAppService(ticket.whatsappId);
//     const { farewellMessage } = whatsapp;
//     if (farewellMessage) {
//        await SendWhatsAppMessage({ body: farewellMessage, ticket });
//     }
//   }
//   return res.status(200).json(ticket);
// };
const remove = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const { ticketId } = req.params;
    const ticket = yield DeleteTicketService_1.default(ticketId);
    const io = socket_1.getIO();
    io.to(ticket.status).to(ticketId).to("notification").emit("ticket", {
        action: "delete",
        ticketId: +ticketId
    });
    yield RedisClient_1.del(`remote:ticketId:${ticketId}`);
    return res.status(200).json({ message: "ticket deleted" });
});
exports.remove = remove;
