"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventPropertyMapper = void 0;
const PropertyMapper_1 = require("../../core/_internal/PropertyMapper");
const upgradeCatalogSchema_1 = require("../../search/upgradeCatalogSchema");
const util_1 = require("../../util");
const orval_events_1 = require("../api/orval/api/orval-events");
const hubEventAttendanceType_1 = require("../enums/hubEventAttendanceType");
const hubEventCapacityType_1 = require("../enums/hubEventCapacityType");
const computeLinks_1 = require("./computeLinks");
const getEventSlug_1 = require("./getEventSlug");
const getLocationFromEvent_1 = require("./getLocationFromEvent");
/**
 * @private
 * Manage forward and backward property mappings to
 * streamline conversion between a Hub Event, and
 * the backing Store objects.
 */
class EventPropertyMapper extends PropertyMapper_1.PropertyMapper {
    /**
     * Map properties from a Store object, on to an Entity object.
     *
     * Used when constructing an Entity from a fetched Store object,
     * in which case the Entity should be an empty object (`{}`).
     *
     * Can also be used to apply changes to an Entity from a Store,
     * in which case an existing Entity can be passed in.
     * @param store
     * @param entity
     * @returns
     */
    storeToEntity(store, entity) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        const obj = (0, PropertyMapper_1.mapStoreToEntity)(store, entity, this.mappings);
        obj.type = "Event";
        const access = store.access.toLowerCase();
        if (access === "private" &&
            (store.readGroups.length > 0 || store.editGroups.length > 0)) {
            obj.access = "shared";
        }
        else {
            obj.access = access;
        }
        obj.isCanceled = store.status === orval_events_1.EventStatus.CANCELED;
        obj.isPlanned = store.status === orval_events_1.EventStatus.PLANNED;
        obj.isRemoved = store.status === orval_events_1.EventStatus.REMOVED;
        if (store.attendanceType.includes(orval_events_1.EventAttendanceType.IN_PERSON) &&
            store.attendanceType.includes(orval_events_1.EventAttendanceType.VIRTUAL)) {
            obj.attendanceType = hubEventAttendanceType_1.HubEventAttendanceType.Both;
        }
        else if (store.attendanceType.includes(orval_events_1.EventAttendanceType.IN_PERSON)) {
            obj.attendanceType = hubEventAttendanceType_1.HubEventAttendanceType.InPerson;
        }
        else {
            obj.attendanceType = hubEventAttendanceType_1.HubEventAttendanceType.Online;
        }
        obj.onlineCapacity = (_b = (_a = store.onlineMeeting) === null || _a === void 0 ? void 0 : _a.capacity) !== null && _b !== void 0 ? _b : null;
        obj.onlineCapacityType = ((_c = store.onlineMeeting) === null || _c === void 0 ? void 0 : _c.capacity)
            ? hubEventCapacityType_1.HubEventCapacityType.Fixed
            : hubEventCapacityType_1.HubEventCapacityType.Unlimited;
        obj.inPersonCapacity = (_d = store.inPersonCapacity) !== null && _d !== void 0 ? _d : null;
        obj.inPersonCapacityType = store.inPersonCapacity
            ? hubEventCapacityType_1.HubEventCapacityType.Fixed
            : hubEventCapacityType_1.HubEventCapacityType.Unlimited;
        obj.onlineDetails = (_f = (_e = store.onlineMeeting) === null || _e === void 0 ? void 0 : _e.details) !== null && _f !== void 0 ? _f : null;
        obj.onlineUrl = (_h = (_g = store.onlineMeeting) === null || _g === void 0 ? void 0 : _g.url) !== null && _h !== void 0 ? _h : null;
        obj.canChangeAccess = [
            store.permission.canSetAccessToPublic,
            store.permission.canSetAccessToOrg,
            store.permission.canSetAccessToPrivate,
        ].every(Boolean);
        obj.canChangeStatus = [
            store.permission.canSetStatusToCancelled,
            store.permission.canSetStatusToRemoved,
        ].some(Boolean);
        obj.referencedContentIds = store.associations.map(({ entityId }) => entityId);
        obj.referencedContentIdsByType = store.associations.map(({ entityId, entityType }) => ({ entityId, entityType }));
        // Handle Dates
        obj.createdDate = new Date(store.createdAt);
        obj.startDateTime = new Date(store.startDateTime);
        obj.endDateTime = new Date(store.endDateTime);
        obj.isPast = obj.endDateTime < new Date();
        obj.createdDateSource = "createdAt";
        obj.updatedDate = new Date(store.updatedAt);
        obj.updatedDateSource = "updatedAt";
        // Ensure we have a catalog and that its at the current schema
        obj.catalog = (0, upgradeCatalogSchema_1.upgradeCatalogSchema)(obj.catalog || {});
        obj.links = (0, computeLinks_1.computeLinks)(store);
        obj.slug = (0, getEventSlug_1.getEventSlug)(store);
        obj.view = {
            showMap: !!store.location,
        };
        obj.location = (0, getLocationFromEvent_1.getLocationFromEvent)(store);
        return obj;
    }
    /**
     * Map properties from an entity object onto a model.
     *
     * Typically the model will already exist, and this
     * method is used to transfer changes to the model
     * prior to storage.
     * @param entity
     * @param store
     * @returns
     */
    entityToStore(entity, store) {
        const clonedEntity = (0, util_1.cloneObject)(entity);
        const obj = (0, PropertyMapper_1.mapEntityToStore)(clonedEntity, store, this.mappings);
        const access = clonedEntity.access;
        if (access === "shared") {
            obj.access = orval_events_1.EventAccess.PRIVATE;
        }
        else {
            obj.access = access.toUpperCase();
        }
        if (clonedEntity.isRemoved) {
            obj.status = orval_events_1.EventStatus.REMOVED;
        }
        else if (clonedEntity.isCanceled) {
            obj.status = orval_events_1.EventStatus.CANCELED;
        }
        else {
            obj.status = orval_events_1.EventStatus.PLANNED;
        }
        if (clonedEntity.attendanceType === hubEventAttendanceType_1.HubEventAttendanceType.Both) {
            obj.attendanceType = [
                orval_events_1.EventAttendanceType.IN_PERSON,
                orval_events_1.EventAttendanceType.VIRTUAL,
            ];
        }
        else if (clonedEntity.attendanceType === hubEventAttendanceType_1.HubEventAttendanceType.InPerson) {
            obj.attendanceType = [orval_events_1.EventAttendanceType.IN_PERSON];
        }
        else {
            obj.attendanceType = [orval_events_1.EventAttendanceType.VIRTUAL];
        }
        if ([hubEventAttendanceType_1.HubEventAttendanceType.Online, hubEventAttendanceType_1.HubEventAttendanceType.Both].includes(clonedEntity.attendanceType)) {
            obj.onlineMeeting = {
                details: clonedEntity.onlineDetails,
                capacity: clonedEntity.onlineCapacityType === hubEventCapacityType_1.HubEventCapacityType.Fixed
                    ? clonedEntity.onlineCapacity
                    : null,
                url: clonedEntity.onlineUrl,
            };
        }
        if ([hubEventAttendanceType_1.HubEventAttendanceType.InPerson, hubEventAttendanceType_1.HubEventAttendanceType.Both].includes(clonedEntity.attendanceType)) {
            obj.inPersonCapacity =
                clonedEntity.inPersonCapacityType === hubEventCapacityType_1.HubEventCapacityType.Fixed
                    ? clonedEntity.inPersonCapacity
                    : null;
        }
        else {
            obj.inPersonCapacity = null;
        }
        // override startTime & endTime for all-day events
        if (clonedEntity.isAllDay) {
            clonedEntity.startTime = "00:00:00";
            clonedEntity.endTime = "23:59:59";
        }
        obj.location =
            clonedEntity.location && clonedEntity.location.type !== "none"
                ? {
                    type: clonedEntity.location.type,
                    spatialReference: clonedEntity.location.spatialReference,
                    extent: clonedEntity.location.extent,
                    geometries: clonedEntity.location.geometries,
                    placeName: clonedEntity.location.name,
                }
                : null;
        return obj;
    }
}
exports.EventPropertyMapper = EventPropertyMapper;
//# sourceMappingURL=PropertyMapper.js.map