"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CalendarService = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@loopback/core");
const lodash_1 = require("lodash");
const moment = tslib_1.__importStar(require("moment"));
const transient_web_site_service_1 = require("../web-site/transient-web-site.service");
const entity_name_1 = require("./../../models/entity-name");
const inside_rest_service_1 = require("./../../services/inside-rest/inside-rest.service");
const object_type_service_1 = require("./../../services/object-type.service");
const transient_entity_service_1 = require("./../../services/transient-entity/transient-entity.service");
const uri_complete_service_1 = require("./../../services/uri-complete/uri-complete.service");
const web_site_service_1 = require("./../web-site/web-site.service");
const calendar_const_1 = require("./calendar.const");
const calendar_interface_1 = require("./calendar.interface");
let CalendarService = class CalendarService {
    constructor(transientEntityService, insideRestService, objectTypeService, uriCompleteService, transientWebSiteService, webSiteService) {
        this.transientEntityService = transientEntityService;
        this.insideRestService = insideRestService;
        this.objectTypeService = objectTypeService;
        this.uriCompleteService = uriCompleteService;
        this.transientWebSiteService = transientWebSiteService;
        this.webSiteService = webSiteService;
        this.transientEntityService.registerTransientEntityTypeFunction(calendar_const_1.CALENDAR_PROVIDER, CalendarService.name, 'Build calendar entries', entity_name_1.EntityName.objectNode, calendar_const_1.CALENDAR_ENTRIES_TYPE.name, this.completeCalendarEntriesNode.bind(this));
        this.transientEntityService.registerTransientEntityTypeFunction(calendar_const_1.CALENDAR_PROVIDER, CalendarService.name, 'Add calendar references to calendar paragraph', entity_name_1.EntityName.objectNode, calendar_const_1.CALENDAR_TYPE.name, this.completeCalendarNode.bind(this));
        this.webSiteService.registerEventContributor(this.contributeToEvent.bind(this), {
            buildEventObjectNode: this.buildEventObjectNode.bind(this),
            declareEventCreationMethod: this.declareEventCreationMethod.bind(this),
        });
        this.webSiteService.registerPopupContributor(this.contributeToPopup.bind(this));
    }
    async completeCalendarNode(objectNode, ctx) {
        var _a, _b, _c, _d, _e, _f, _g;
        if (!objectNode.calendarEntriesObjectTreeId && ((_d = (_c = (_b = (_a = objectNode.entityCtx) === null || _a === void 0 ? void 0 : _a.jsonSchema) === null || _b === void 0 ? void 0 : _b.properties) === null || _c === void 0 ? void 0 : _c.calendarEntriesObjectTreeId) === null || _d === void 0 ? void 0 : _d.oneOf) &&
            objectNode.entityCtx.jsonSchema.properties.calendarEntriesObjectTreeId
                .oneOf.length > 0) {
            objectNode.calendarEntriesObjectTreeId =
                objectNode.entityCtx.jsonSchema.properties.calendarEntriesObjectTreeId.oneOf[0].enum[0];
        }
        if (objectNode.calendarEntriesObjectTreeId &&
            !objectNode.calendarEntriesObjectTreeUri) {
            objectNode.calendarEntriesObjectTreeUri = this.uriCompleteService.getUri(entity_name_1.EntityName.objectTree, objectNode.calendarEntriesObjectTreeId, ctx);
        }
        if (objectNode.calendarEntriesObjectTreeId) {
            objectNode.calendarEntriesObjectNodeUri = this.uriCompleteService.getUri(entity_name_1.EntityName.objectNode, objectNode.calendarEntriesObjectTreeId, ctx);
        }
        if (objectNode.calendarEntriesObjectNodeUri) {
            try {
                const calendarEntriesNode = (await this.insideRestService.read(objectNode.calendarEntriesObjectNodeUri, ctx));
                if (calendarEntriesNode === null || calendarEntriesNode === void 0 ? void 0 : calendarEntriesNode.calendarEntriesList) {
                    const oneOf = [];
                    for (const entryKey of Object.keys(calendarEntriesNode.calendarEntriesList)) {
                        oneOf.push({
                            enum: [entryKey],
                            title: calendarEntriesNode.calendarEntriesList[entryKey].title,
                        });
                    }
                    if (0 < oneOf.length && ((_g = (_f = (_e = objectNode.entityCtx) === null || _e === void 0 ? void 0 : _e.jsonSchema) === null || _f === void 0 ? void 0 : _f.properties) === null || _g === void 0 ? void 0 : _g.calendarEntryKey)) {
                        objectNode.entityCtx.jsonSchema.properties.calendarEntryKey.oneOf = oneOf;
                        if (!objectNode.calendarEntryKey) {
                            objectNode.calendarEntryKey = oneOf[0].enum[0];
                        }
                    }
                }
            }
            catch (error) { }
        }
        if (objectNode.calendarEntriesObjectNodeUri &&
            objectNode.calendarEntryKey) {
            try {
                const calendarEntriesNode = (await this.insideRestService.read(objectNode.calendarEntriesObjectNodeUri, ctx));
                moment.locale(ctx.uriContext.uri.value.acceptLanguage);
                const calendar = calendarEntriesNode.calendarEntriesList[objectNode.calendarEntryKey];
                const minDate = moment.utc(calendar.minDate);
                const maxDate = moment.utc(calendar.maxDate);
                calendar.months = [];
                for (let month = moment.default(minDate).startOf('month'); !month.isAfter(maxDate); month = month.add(1, 'month')) {
                    calendar.months.push({
                        firstMonthWeekDay: ((month.startOf('month').day() + 6) % 7),
                        monthLabel: month.format('MMMM YYYY'),
                        monthDays: moment.default(month).endOf('month').date(),
                        id: month.year() * 10000 + month.month() * 100,
                    });
                }
                for (const date of calendar.dates) {
                    const from = moment.utc(date.from);
                    date.fromId = from.year() * 10000 + from.month() * 100 + from.date();
                    const to = moment.utc(date.to);
                    date.toId = to.year() * 10000 + to.month() * 100 + to.date();
                }
                calendar.dates.sort((a, b) => a.fromId - b.fromId);
                calendar.days = {
                    0: moment.default().day(1).format('ddd'),
                    1: moment.default().day(2).format('ddd'),
                    2: moment.default().day(3).format('ddd'),
                    3: moment.default().day(4).format('ddd'),
                    4: moment.default().day(5).format('ddd'),
                    5: moment.default().day(6).format('ddd'),
                    6: moment.default().day(0).format('ddd'),
                };
                objectNode.calendar = calendar;
            }
            catch (error) { }
        }
    }
    async getCalendarMenuEntries(entriesTree, calendarMenus, menuEntryDef, ctx) {
        let dates = undefined;
        if (0 < calendarMenus.length) {
            const initRange = this.getDateRange(calendarMenus[0].menuTitle);
            dates = {
                minDateUtc: initRange.from,
                maxDateUtc: initRange.to,
                minDate: initRange.from.format('YYYY-MM-DD'),
                maxDate: initRange.to.format('YYYY-MM-DD'),
                dates: [],
                key: menuEntryDef.entryKey,
                title: menuEntryDef.entryName,
            };
            await this.buildCalendarDates(entriesTree, dates, calendarMenus, ctx);
        }
        return dates;
    }
    async completeCalendarEntriesNode(calenderEntriesNode, ctx) {
        calenderEntriesNode.calendarEntriesList = {};
        try {
            const webSiteTree = (await this.insideRestService.read(calenderEntriesNode.webSiteObjectTreeUri, ctx));
            const implementingCalendarEntry = await this.objectTypeService.getImplementingTypes(calendar_const_1.CALENDAR_ENTRY_TYPE.name);
            for (const menuEntryDef of webSiteTree.treeNode.menuEntries) {
                if (lodash_1.intersection(implementingCalendarEntry, menuEntryDef.entryTypes)
                    .length > 0) {
                    const calenderEntriesTree = (await this.insideRestService.read(this.uriCompleteService.getUri(entity_name_1.EntityName.objectTree, calenderEntriesNode.id, ctx), ctx));
                    const menuTrees = calenderEntriesNode.menuEntriesList &&
                        menuEntryDef.entryKey in calenderEntriesNode.menuEntriesList
                        ? calenderEntriesNode.menuEntriesList[menuEntryDef.entryKey]
                            .children
                        : await this.transientWebSiteService.lookForMenuEntries([calenderEntriesTree], menuEntryDef.entryTypes, calenderEntriesTree, menuEntryDef.entryKey, menuEntryDef.menuEntryLabelKey
                            ? menuEntryDef.menuEntryLabelKey
                            : 'name', !!menuEntryDef.adminEntry);
                    calenderEntriesNode.calendarEntriesList[menuEntryDef.entryKey] = await this.getCalendarMenuEntries(calenderEntriesTree, menuTrees, menuEntryDef, ctx);
                }
            }
        }
        catch (error) { }
    }
    async buildCalendarDates(entriesTree, dates, children, ctx) {
        var _a, _b;
        for (const calendarEntry of children) {
            const newDate = await this.buildCalendarEntry(entriesTree, calendarEntry, ctx);
            if (newDate) {
                if ((_a = newDate.fromUtc) === null || _a === void 0 ? void 0 : _a.isBefore(dates.minDateUtc)) {
                    dates.minDateUtc = newDate.fromUtc;
                    dates.minDate = dates.minDateUtc.format('YYYY-MM-DD');
                }
                if ((_b = newDate.toUtc) === null || _b === void 0 ? void 0 : _b.isAfter(dates.maxDateUtc)) {
                    dates.maxDateUtc = newDate.toUtc;
                    dates.maxDate = dates.maxDateUtc.format('YYYY-MM-DD');
                }
                dates.dates.push(newDate);
            }
            if (calendarEntry.children && 0 < calendarEntry.children.length) {
                await this.buildCalendarDates(entriesTree, dates, calendarEntry.children, ctx);
            }
        }
    }
    async buildCalendarEntry(entriesTree, menuTree, ctx) {
        let event = undefined;
        if (menuTree.treeNode.calendarDateRange) {
            event = await this.webSiteService.buildEvent(entriesTree, menuTree, calendar_interface_1.CalendarEntryNode, ctx);
        }
        return event;
    }
    async declareEventCreationMethod(methodDefinition) {
        var _a;
        Object.assign(methodDefinition.parameters.properties, (_a = calendar_const_1.CALENDAR_ENTRY_TYPE.definition) === null || _a === void 0 ? void 0 : _a.properties);
    }
    async buildEventObjectNode(objectNode, args) {
        if (args.calendarDateRange) {
            objectNode.calendarDateRange = args.calendarDateRange;
        }
    }
    async contributeToEvent(webSiteEvent, entriesTree, menuTree, ctx) {
        if (menuTree.treeNode.calendarDateRange) {
            const range = this.getDateRange(menuTree.treeNode.calendarDateRange);
            menuTree.range = menuTree.treeNode.calendarDateRange;
            moment.locale(ctx.uriContext.uri.value.acceptLanguage);
            let menuTitle = range.from.format('LL');
            if (!lodash_1.isEqual(range.from, range.to)) {
                menuTitle += ' - ' + range.to.format('LL');
            }
            webSiteEvent.addEventMenuTitle(menuTitle, calendar_interface_1.CalendarEntryNode.TYPE);
            webSiteEvent.addSpecificFields({
                range: menuTree.range,
                fromUtc: range.from,
                toUtc: range.to,
                from: range.from.format('YYYY-MM-DD'),
                to: range.to.format('YYYY-MM-DD'),
            });
        }
        return true;
    }
    async contributeToPopup(popupNode, builder, ctx) {
        if (popupNode.calendarDateRange) {
            const range = this.getDateRange(popupNode.calendarDateRange);
            popupNode = popupNode.calendarDateRange;
            moment.locale(ctx.uriContext.uri.value.acceptLanguage);
            let menuTitle = range.from.format('LL');
            if (!lodash_1.isEqual(range.from, range.to)) {
                menuTitle += ' - ' + range.to.format('LL');
            }
            if (menuTitle &&
                -1 === lodash_1.indexOf(builder.popupParts.subTitleParts, menuTitle) &&
                menuTitle !== builder.popupParts.title) {
                builder.popupParts.subTitleParts.push(menuTitle);
            }
        }
        return true;
    }
    getDateRange(dateRange) {
        const dates = {
            from: moment.utc(),
            to: moment.utc(),
        };
        if ('' !== dateRange) {
            const ranges = dateRange.split(' ');
            if (2 === ranges.length) {
                dates.from = moment.utc(ranges[0]);
                dates.to = moment.utc(ranges[1]);
            }
        }
        return dates;
    }
};
CalendarService = tslib_1.__decorate([
    tslib_1.__param(0, core_1.service(transient_entity_service_1.TransientEntityService)),
    tslib_1.__param(1, core_1.service(inside_rest_service_1.InsideRestService)),
    tslib_1.__param(2, core_1.service(object_type_service_1.ObjectTypeService)),
    tslib_1.__param(3, core_1.service(uri_complete_service_1.UriCompleteService)),
    tslib_1.__param(4, core_1.service(transient_web_site_service_1.TransientWebSiteService)),
    tslib_1.__param(5, core_1.service(web_site_service_1.WebSiteService)),
    tslib_1.__metadata("design:paramtypes", [transient_entity_service_1.TransientEntityService,
        inside_rest_service_1.InsideRestService,
        object_type_service_1.ObjectTypeService,
        uri_complete_service_1.UriCompleteService,
        transient_web_site_service_1.TransientWebSiteService,
        web_site_service_1.WebSiteService])
], CalendarService);
exports.CalendarService = CalendarService;
//# sourceMappingURL=calendar.service.js.map