"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CalendarService = void 0;
const axios_1 = __importDefault(require("axios"));
const dayjs_1 = __importDefault(require("dayjs"));
const CalandarDay_model_1 = __importDefault(require("../models/CalandarDay.model"));
class CalendarService {
    calendarRepository;
    constructor(calendarRepository) {
        this.calendarRepository = calendarRepository;
    }
    /**
     * Download a calendar from working days API and save it to DB.
     * It will download all days between startDate and endDate inclusive,
     * for example,
     * startDate as 2025-01-01
     * endDate as 2026-01-01
     */
    async fulfillCalendar(startDate, endDate) {
        const getDays = () => {
            const days = [];
            const start = (0, dayjs_1.default)(startDate);
            const end = (0, dayjs_1.default)(endDate);
            for (let day = (0, dayjs_1.default)(start); day.isBefore(end); day = day.add(1, 'day')) {
                days.push(day.format('YYYY-MM-DD'));
            }
            return days;
        };
        const options = (date) => ({
            method: 'GET',
            url: 'https://working-days.p.rapidapi.com/1.3/get_info_day',
            params: {
                country_code: 'US',
                date,
            },
            headers: {
                'X-RapidAPI-Key': '07a550d083msh90e492b0eeb739cp180bb6jsn4005ea3ba2a7',
                'X-RapidAPI-Host': 'working-days.p.rapidapi.com',
            },
        });
        try {
            const dates = getDays();
            const datesToCreate = [];
            await Promise.all(dates.map(async (date) => {
                const foundDate = await CalandarDay_model_1.default.findOne({ date });
                if (!foundDate) {
                    datesToCreate.push(date);
                }
            }));
            await Promise.all(datesToCreate.map(async (date, i) => {
                setTimeout(async () => {
                    const response = await axios_1.default.request(options(date));
                    await this.createDate(date, response.data);
                    console.log('created', date);
                    if (datesToCreate.length === i + 1) {
                        console.log('done!');
                    }
                }, i * 500);
            }));
        }
        catch (error) {
            console.error(error);
        }
    }
    async createDate(date, dateProp) {
        const newDate = {
            date: date,
            customDate: dateProp.custom_date === 1,
            customDateDescription: dateProp.custom_date_description,
            publicHoliday: dateProp.public_holiday === '1',
            publicHolidayDescription: dateProp.public_holiday_description,
            weekendDay: dateProp.weekend_day === 1,
            workingDay: dateProp.working_day === 1,
        };
        await CalandarDay_model_1.default.create(newDate);
    }
    async isWorkingDay(date) {
        const calendarDay = await CalandarDay_model_1.default.findOne({ date });
        return calendarDay.workingDay;
    }
    async isLastWorkingDay(date) {
        const calendarDay = await CalandarDay_model_1.default.findOne({ date });
        const isNextDayWorking = await this.isWorkingDay((0, dayjs_1.default)(calendarDay.date).add(1, 'day').format('YYYY-MM-DD'));
        return !isNextDayWorking;
    }
    async getNextWorkingDay(date) {
        return this.calendarRepository.getNextWorkingDay(date);
    }
    async getLastWorkingDay(date) {
        let previous = (0, dayjs_1.default)(new Date(date));
        let isWorking = false;
        do {
            previous = previous.subtract(1, 'day');
            const calendarDay = await CalandarDay_model_1.default.findOne({ date: previous.format('YYYY-MM-DD') }).lean();
            if (!calendarDay) {
                console.error(`no data in calendar for ${previous.format('YYYY-MM-DD')}`);
            }
            isWorking = calendarDay ? calendarDay.workingDay : true;
        } while (isWorking === false);
        return previous.format('YYYY-MM-DD');
    }
    async getFullCalendarList() {
        return CalandarDay_model_1.default.find().sort({ date: 1 }).lean();
    }
}
exports.CalendarService = CalendarService;
