"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Room = void 0;
const RoomRate_1 = require("./RoomRate");
class Room {
    constructor(props) {
        this.auxiliaryValues = {};
        this.getLowestPriceType = (raw = false) => {
            var _a, _b;
            return ((_b = (_a = (raw ? this.rates : this.filteredRates)
                .reduce((sum, rate) => {
                return sum && sum.getAveragePrice() < rate.getAveragePrice() ? sum : rate;
            }, null)) === null || _a === void 0 ? void 0 : _a.getPriceType()) !== null && _b !== void 0 ? _b : RoomRate_1.RoomRatePriceInclusion.IncludingFeesAndTaxes);
        };
        this.rates = [];
        this.images = [];
        this.auxiliaryValues = {};
        if (props) {
            this.applyData(props);
        }
    }
    static fromData(data) {
        const room = new this();
        if (!data.images && data.imageUrls) {
            data.images = data.imageUrls;
        }
        room.applyData(data);
        return room;
    }
    getShortDescription(trim = true) {
        var _a, _b;
        let shortDesc = this.shortDescription;
        if (trim) {
            shortDesc = ((_a = this.shortDescription) === null || _a === void 0 ? void 0 : _a.length) > 97 ? ((_b = this.shortDescription) === null || _b === void 0 ? void 0 : _b.substr(0, 97)) + '…' : this.shortDescription;
        }
        return shortDesc === null || shortDesc === void 0 ? void 0 : shortDesc.replace(/(<br>\s*)+$/, '');
    }
    getLongDescription() {
        var _a;
        return (_a = this.longDescription) === null || _a === void 0 ? void 0 : _a.replace(/(<br>\s*)+$/, '');
    }
    applyData(data) {
        Object.keys(data).map((key) => {
            this[key] = data[key];
        }, this);
        this.filteredRates = this.rates;
    }
    getLowestPrice(raw = false, rawPrice = false) {
        var _a, _b;
        return ((_b = (_a = (raw ? this.rates : this.filteredRates)) === null || _a === void 0 ? void 0 : _a.reduce((sum, rate) => {
            const avrg = rate.getAveragePrice(rawPrice);
            return sum < avrg && sum ? sum : avrg;
        }, 0)) !== null && _b !== void 0 ? _b : 0);
    }
    /**
     * Function for getting the lowest total price of the room from all the possible rates.
     * @param includeAllRates If set to true will include all rates, otherwise will only include filtered rates
     * @param getCost If set to true will return the cost of the rate, otherwise will return the average price see {@link RoomRate.getTotalPrice}
     * @returns
     */
    getLowestTotalPrice(includeAllRates = false, getCost = false) {
        var _a, _b;
        return ((_b = (_a = (includeAllRates ? this.rates : this.filteredRates)) === null || _a === void 0 ? void 0 : _a.reduce((sum, rate) => {
            const avrg = rate.getTotalPrice(getCost);
            return sum < avrg && sum ? sum : avrg;
        }, 0)) !== null && _b !== void 0 ? _b : 0);
    }
    getHighestPrice(raw = false) {
        var _a, _b;
        return ((_b = (_a = (raw ? this.rates : this.filteredRates)) === null || _a === void 0 ? void 0 : _a.reduce((sum, rate) => (sum > rate.getAveragePrice() && sum ? sum : rate.getAveragePrice()), 0)) !== null && _b !== void 0 ? _b : 0);
    }
    addRate(rate) {
        rate.setRoom(this);
        this.rates.push(rate);
    }
    getImages() {
        if (this.images && this.images.length) {
            return this.images;
        }
        return [];
    }
    getOriginalRates() {
        return this.rates;
    }
    getRates() {
        return this.filteredRates.sort((a, b) => {
            return a.isMemberOnly ? -1 : b.isMemberOnly ? 1 : 0;
        });
    }
    getRate(code) {
        for (const rate in this.rates) {
            if (code === this.rates[rate].code) {
                return this.rates[rate];
            }
        }
        return null;
    }
    getPriceSortValue() {
        return this.getLowestPrice();
    }
    getRecommendedSortValue() {
        return this.order;
    }
    getOrderSortValue() {
        return this.order;
    }
    serialize() {
        const toSerialize = {
            id: this.id,
            code: this.code,
            images: this.images,
            longDescription: this.longDescription,
            name: this.name,
            occupancy: this.occupancy,
            rates: this.rates.map((rate) => rate.serialize()),
            shortDescription: this.shortDescription,
            roomGroupId: this.roomGroupId,
            auxiliaryValues: this.auxiliaryValues,
            order: this.order,
        };
        return toSerialize;
    }
    unSerialize(data) {
        var _a;
        const newRates = (_a = data.rates) === null || _a === void 0 ? void 0 : _a.map((serializedRate) => {
            const roomRate = new RoomRate_1.RoomRate();
            roomRate.unSerialize(serializedRate);
            return roomRate;
        });
        this.code = data.code;
        this.id = data.id;
        this.images = data.images;
        this.longDescription = data.longDescription;
        this.name = data.name;
        this.occupancy = data.occupancy;
        this.shortDescription = data.shortDescription;
        this.filteredRates = newRates;
        this.rates = newRates;
        this.roomGroupId = data.roomGroupId;
        this.auxiliaryValues = data.auxiliaryValues;
        this.order = data.order;
        return this;
    }
    getRoomPerks({ hotel, room, perksLimitNumber }) {
        var _a, _b, _c;
        if (!room || !hotel) {
            return {
                roomPerks: (_a = hotel === null || hotel === void 0 ? void 0 : hotel.perks) !== null && _a !== void 0 ? _a : [],
            };
        }
        const roomOverride = (_b = hotel === null || hotel === void 0 ? void 0 : hotel.overwrites) === null || _b === void 0 ? void 0 : _b[room === null || room === void 0 ? void 0 : room.code];
        let roomPerks = ((_c = roomOverride === null || roomOverride === void 0 ? void 0 : roomOverride.perks) === null || _c === void 0 ? void 0 : _c.length) ? roomOverride === null || roomOverride === void 0 ? void 0 : roomOverride.perks : hotel === null || hotel === void 0 ? void 0 : hotel.perks;
        if (perksLimitNumber) {
            roomPerks = roomPerks === null || roomPerks === void 0 ? void 0 : roomPerks.slice(0, perksLimitNumber);
        }
        const prePerkDisclaimer = (roomOverride === null || roomOverride === void 0 ? void 0 : roomOverride.prePerkDisclaimer) ? roomOverride.prePerkDisclaimer : room === null || room === void 0 ? void 0 : room.prePerkDisclaimer;
        return {
            prePerkDisclaimer: prePerkDisclaimer,
            roomPerks: roomPerks !== null && roomPerks !== void 0 ? roomPerks : [],
        };
    }
    isAvailable() {
        var _a;
        const rates = (_a = this.filteredRates) !== null && _a !== void 0 ? _a : this.rates;
        return rates.some((rate) => Object.values(rate.nightRates).every((nightRate) => nightRate.available));
    }
}
exports.Room = Room;
//# sourceMappingURL=Room.js.map