"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 });
const sequelize_1 = require("sequelize");
const date_fns_1 = require("date-fns");
const pt_BR_1 = __importDefault(require("date-fns/locale/pt-BR"));
const Ticket_1 = __importDefault(require("../../models/Ticket"));
const Contact_1 = __importDefault(require("../../models/Contact"));
const Message_1 = __importDefault(require("../../models/Message"));
const Queue_1 = __importDefault(require("../../models/Queue"));
const ShowUserService_1 = __importDefault(require("../UserServices/ShowUserService"));
const unflatten = require("flat").unflatten;
const SplitDateTime_1 = require("../../helpers/SplitDateTime");
const dateToday = SplitDateTime_1.splitDateTime(new Date(date_fns_1.format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: pt_BR_1.default })));
const User_1 = __importDefault(require("../../models/User"));
const RedisClient_1 = require("../../helpers/RedisClient");
const MonthsAgo_1 = __importDefault(require("../../helpers/MonthsAgo"));
const ListTicketsService = ({ searchParam = "", pageNumber = "1", queueIds, status, date, showAll, userId, withUnreadMessages, unlimited = "false", searchParamContent = "" }) => __awaiter(void 0, void 0, void 0, function* () {
    console.log("----------> searchParamContent: ", searchParamContent, " | searchParam: ", searchParam);
    let whereCondition = {
        [sequelize_1.Op.or]: [{ userId }, { status: "pending" }],
        queueId: { [sequelize_1.Op.or]: [queueIds, null] }
    };
    console.log("PAGE NUMBER TICKET: ", pageNumber);
    if (pageNumber.trim().length == 0) {
        pageNumber = "1";
    }
    // if (searchParam && searchParam.trim().length > 0 && process.env.CACHE) {
    //   try {
    //     const offset = 40 * (+pageNumber - 1);
    //     searchParam = searchParam.replace(/\s+/g, " ").trim().toLowerCase();
    //     console.log("QUERY TICKET SEARCH PARAM FROM CACHE: ", searchParam);
    //     let tickets: any = await searchTicketCache(searchParam, offset, 40);
    //     if (tickets) {
    //       console.log(
    //         "QUERY TICKET SEARCH PARAM FROM CACHE LENGTH...: ",
    //         tickets.length
    //       );
    //       tickets.map((t: any) => {
    //         t["contact.number"] = t["contact_number"];
    //         delete t["contact_number"];
    //         return { ...["contact_number"] };
    //       });
    //       tickets = tickets.map((e: any) => unflatten(e));
    //       return {
    //         tickets,
    //         count: tickets.length,
    //         hasMore: tickets.length > 0 ? true : false
    //       };
    //     }
    //   } catch (error) {
    //     console.log(
    //       "There was an error on search ListTicketservice.ts search cache: ",
    //       error
    //     );
    //   }
    //   console.log("QUERY TICKETS FROM DATABASE...");
    // }
    let includeCondition;
    includeCondition = [
        {
            model: Contact_1.default,
            as: "contact",
            attributes: ["id", "name", "number", "profilePicUrl"]
        },
        {
            model: Queue_1.default,
            as: "queue",
            attributes: ["id", "name", "color"]
        }
    ];
    if (showAll === "true") {
        whereCondition = { queueId: { [sequelize_1.Op.or]: [queueIds, null] } };
    }
    if (status) {
        whereCondition = Object.assign(Object.assign({}, whereCondition), { status });
        if (unlimited === "current" && status !== "pending") {
            whereCondition = Object.assign(Object.assign({}, whereCondition), { createdAt: {
                    [sequelize_1.Op.gte]: dateToday.fullDate + " 00:00:00.000000",
                    [sequelize_1.Op.lte]: dateToday.fullDate + " 23:59:59.999999"
                } });
        }
    }
    if (searchParam) {
        const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim();
        includeCondition = [
            ...includeCondition,
            {
                model: Message_1.default,
                as: "messages",
                attributes: ["id", "body"],
                where: {
                    body: sequelize_1.where(sequelize_1.fn("LOWER", sequelize_1.col("body")), "LIKE", `%${sanitizedSearchParam}%`)
                },
                required: false,
                duplicating: false
            }
        ];
        whereCondition = Object.assign(Object.assign({}, whereCondition), { createdAt: {
                [sequelize_1.Op.gte]: MonthsAgo_1.default(4) + " 00:00:00.000000",
                [sequelize_1.Op.lte]: dateToday.fullDate + " 23:59:59.999999"
            } });
        whereCondition = Object.assign(Object.assign({}, whereCondition), { [sequelize_1.Op.or]: [
                {
                    "$contact.name$": sequelize_1.where(sequelize_1.fn("LOWER", sequelize_1.col("contact.name")), "LIKE", `%${sanitizedSearchParam}%`)
                },
                { "$contact.number$": { [sequelize_1.Op.like]: `%${sanitizedSearchParam}%` } },
                {
                    "$message.body$": sequelize_1.where(sequelize_1.fn("LOWER", sequelize_1.col("body")), "LIKE", `%${sanitizedSearchParam}%`)
                }
            ] });
        // const sanitizedSearchParamContent = searchParamContent
        //   .toLocaleLowerCase()
        //   .trim();
        // if (searchParamContent.length > 0) {
        //   includeCondition = [
        //     ...includeCondition,
        //     {
        //       model: Message,
        //       as: "messages",
        //       attributes: ["id", "body"],
        //       where: {
        //         body: where(
        //           fn("LOWER", col("body")),
        //           "LIKE",
        //           `%${sanitizedSearchParamContent}%`
        //         )
        //       },
        //       required: false,
        //       duplicating: false
        //     }
        //   ];
        //   whereCondition = {
        //     ...whereCondition,
        //     "$message.body$": where(
        //       fn("LOWER", col("body")),
        //       "LIKE",
        //       `%${sanitizedSearchParamContent}%`
        //     )
        //   };
        // }
        // whereCondition = {
        //   ...whereCondition,
        //   [Op.or]: [
        //     {
        //       "$contact.name$": where(
        //         fn("LOWER", col("contact.name")),
        //         "LIKE",
        //         `%${sanitizedSearchParam}%`
        //       )
        //     },
        //     { "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }
        //   ]
        // };
        const userProfile = yield User_1.default.findByPk(userId);
        if (userProfile.dataValues.profile != "admin" &&
            userProfile.dataValues.profile != "master" &&
            userProfile.dataValues.profile != "supervisor") {
            whereCondition = Object.assign(Object.assign({}, whereCondition), { userId });
        }
    }
    if (date) {
        whereCondition = {
            createdAt: {
                [sequelize_1.Op.between]: [+date_fns_1.startOfDay(date_fns_1.parseISO(date)), +date_fns_1.endOfDay(date_fns_1.parseISO(date))]
            },
            queueId: { [sequelize_1.Op.or]: [queueIds, null] },
        };
    }
    if (withUnreadMessages === "true") {
        const user = yield ShowUserService_1.default(userId);
        const userQueueIds = user.queues.map(queue => queue.id);
        whereCondition = {
            [sequelize_1.Op.or]: [{ userId }, { status: "pending" }],
            queueId: { [sequelize_1.Op.or]: [userQueueIds, null] },
            unreadMessages: { [sequelize_1.Op.gt]: 0 }
        };
    }
    let limit;
    if (unlimited === "current")
        limit = 10000;
    else if (unlimited === "all")
        limit = 100;
    else
        limit = 40;
    // const limit = unlimited === "current" || unlimited === "all" ? 1000 : 40;
    const offset = limit * (+pageNumber - 1);
    console.log("kkkkkkkkk limit: ", limit);
    let { count, rows: tickets } = yield Ticket_1.default.findAndCountAll({
        where: whereCondition,
        include: includeCondition,
        distinct: true,
        limit,
        offset,
        order: [["updatedAt", "DESC"]]
    });
    const hasMore = count > offset + tickets.length;
    const ticketIds = yield RedisClient_1.get({ key: `remote:controll`, parse: true });
    return {
        tickets,
        count,
        hasMore,
        remoteTicketsControll: ticketIds ? ticketIds : []
    };
});
exports.default = ListTicketsService;
