"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 AppError_1 = __importDefault(require("../../errors/AppError"));
const UserOnlineTime_1 = __importDefault(require("../../models/UserOnlineTime"));
const SplitDateTime_1 = require("../../helpers/SplitDateTime");
const sequelize_1 = require("sequelize");
const date_fns_1 = require("date-fns");
const format_1 = __importDefault(require("date-fns/format"));
const pt_BR_1 = __importDefault(require("date-fns/locale/pt-BR"));
const socket_1 = require("../../libs/socket");
const User_1 = __importDefault(require("../../models/User"));
const formatDateTimeString = (date) => {
    let newDate = new Date();
    newDate.setUTCHours(date.getHours());
    newDate.setUTCMinutes(date.getMinutes());
    newDate.setUTCSeconds(date.getSeconds());
    const newD = new Date(newDate);
    const newDateString = newD.toJSON().slice(0, 19).replace('T', ' ');
    return newDateString;
};
const CreateOrUpdateUserOnlineTime = ({ userId, status, }) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const io = socket_1.getIO();
        let userOnlineTime = null;
        const user = yield User_1.default.findOne({ where: { id: userId } });
        if (!user) {
            return userOnlineTime;
        }
        let dateTime = SplitDateTime_1.splitDateTime(new Date(format_1.default(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: pt_BR_1.default })));
        userOnlineTime = yield UserOnlineTime_1.default.findOne({
            where: {
                [sequelize_1.Op.and]: [
                    {
                        userId: userId
                    },
                    {
                        "$createdAt$": sequelize_1.Sequelize.where(sequelize_1.Sequelize.fn("date", sequelize_1.Sequelize.col("createdAt")), `${dateTime.fullDate}`)
                    },
                ]
            }
        });
        if (userOnlineTime) {
            try {
                let oldStatus = userOnlineTime.status;
                if (oldStatus == 'online' && status === 'offline') {
                    //updatedAt
                    let newtTime = date_fns_1.intervalToDuration({ start: userOnlineTime.updatedAt, end: new Date() });
                    let onlineTime = new Date();
                    onlineTime.setUTCHours(userOnlineTime.onlineTime.getHours());
                    onlineTime.setUTCMinutes(userOnlineTime.onlineTime.getMinutes());
                    onlineTime.setUTCSeconds(userOnlineTime.onlineTime.getSeconds());
                    if (newtTime.hours && +newtTime.hours > 0) {
                        onlineTime = date_fns_1.addHours(onlineTime, newtTime.hours);
                    }
                    if (newtTime.minutes && +newtTime.minutes > 0) {
                        onlineTime = date_fns_1.addMinutes(onlineTime, newtTime.minutes);
                    }
                    if (newtTime.seconds && +newtTime.seconds > 0) {
                        onlineTime = date_fns_1.addSeconds(onlineTime, newtTime.seconds);
                    }
                    const isoDate = new Date(onlineTime);
                    const mySQLDateString = isoDate.toJSON().slice(0, 19).replace('T', ' ');
                    yield userOnlineTime.update({ status, onlineTime: mySQLDateString });
                    //test del  
                    const updatedAtString = formatDateTimeString(userOnlineTime.updatedAt);
                    const createdAtString = formatDateTimeString(userOnlineTime.createdAt);
                    // 
                    io.emit("onlineStatus", {
                        action: "update",
                        userOnlineTime: {
                            userId: userOnlineTime.userId,
                            status: userOnlineTime.status,
                            onlineTime: mySQLDateString,
                            createdAt: createdAtString,
                            updatedAt: updatedAtString
                        }
                    });
                }
                else if (oldStatus == 'offline' && status === 'online') {
                    yield userOnlineTime.update({ status });
                    io.emit("onlineStatus", {
                        action: "update",
                        userOnlineTime: {
                            userId: userOnlineTime.userId,
                            status: userOnlineTime.status,
                            createdAt: formatDateTimeString(userOnlineTime.createdAt),
                            updatedAt: formatDateTimeString(userOnlineTime.updatedAt)
                        }
                    });
                }
                else {
                    console.log('NOT UPDATED THE USER: ', userOnlineTime.userId);
                }
            }
            catch (err) {
                throw new AppError_1.default("ERR_NO_USER_ONLINE_FOUND", 404);
            }
        }
        if (!userOnlineTime) {
            userOnlineTime = yield UserOnlineTime_1.default.create({
                userId,
                status,
                onlineTime: `${dateTime.fullDate} 00:00:00`
            });
            io.emit("onlineStatus", {
                action: "update",
                userOnlineTime: {
                    userId: userOnlineTime.userId,
                    status: userOnlineTime.status,
                    createdAt: formatDateTimeString(userOnlineTime.createdAt),
                    updatedAt: formatDateTimeString(userOnlineTime.updatedAt)
                }
            });
        }
        return userOnlineTime;
    }
    catch (error) {
        console.error('===> Error on CreateOrUpdateUserOnlineTime.ts file: \n', error);
        throw new AppError_1.default(error.message);
    }
});
exports.default = CreateOrUpdateUserOnlineTime;
