"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleAnalytics4 = void 0;
const dayjs_1 = __importDefault(require("dayjs"));
const Analytics_1 = require("./Analytics");
const DATALAYER_DATE_FORMAT = 'YYYY-M-D';
class GoogleAnalytics4 extends Analytics_1.Analytics {
    formatDateRange(dateRange) {
        if (!dateRange)
            return '';
        return `ci:${dateRange.from.format('YYYY-MM-DD')} co:${dateRange.to.format('YYYY-MM-DD')}`;
    }
    generateRoomRateProductInfo(room, dateRange, rate, listPosition, quantity, coupon, extra) {
        var _a, _b, _c, _d, _e, _f;
        const providerId = (_a = this.hotel) === null || _a === void 0 ? void 0 : _a.providerHotelID;
        // For some reason GA4 seems to require pricing to be displayed as a whole, not per night.
        const price = rate ? rate.getTotalPrice() : room.getLowestTotalPrice();
        const discount = rate ? rate.getTotalDiscount() : 0;
        const idParts = [providerId, room.code];
        if (rate) {
            idParts.push(rate.code);
        }
        let upgrade = undefined;
        let upgrade_price_dif = undefined;
        if ((_b = extra === null || extra === void 0 ? void 0 : extra.upsell) === null || _b === void 0 ? void 0 : _b.originalRoomRate) {
            const oldRate = extra.upsell.originalRoomRate;
            upgrade = `${room.name} to ${oldRate.name}`;
            const oldPrice = oldRate ? oldRate.getTotalPrice() : room.getLowestTotalPrice();
            upgrade_price_dif = Math.abs(price - oldPrice); // We're assuming that old is always cheaper, since Upsell is trying to make you spend more
        }
        return {
            item_name: ((_c = this.company) === null || _c === void 0 ? void 0 : _c.brandSuffix) + ' Accommodation',
            item_id: idParts.join(' - '),
            item_brand: [(_d = this.hotel) === null || _d === void 0 ? void 0 : _d.name, providerId].filter(Boolean).join(' - '),
            item_category: 'Room',
            item_category2: (rate === null || rate === void 0 ? void 0 : rate.name) || undefined,
            item_category3: room.name,
            item_category5: ((_e = this.hotel) === null || _e === void 0 ? void 0 : _e.name) + ' Room',
            item_list_name: this.itemListName,
            coupon,
            discount,
            index: listPosition || 0,
            price,
            quantity: quantity || 1,
            selected_dates: (_f = this.formatDateRange({ from: dateRange.from, to: dateRange.to })) !== null && _f !== void 0 ? _f : undefined,
            upgrade,
            upgrade_price_dif,
        };
    }
    generateAddonProductInfo(room, listPosition) {
        var _a, _b, _c, _d;
        const providerId = (_a = this.hotel) === null || _a === void 0 ? void 0 : _a.providerHotelID;
        const price = room.getTotalPrice();
        const idParts = [providerId, room.getAddon().code];
        return {
            // This is still accommodation as it's part of a greater category.
            item_name: ((_b = this.company) === null || _b === void 0 ? void 0 : _b.brandSuffix) + ' Accommodation',
            item_id: idParts.join(' - '),
            item_brand: [(_c = this.hotel) === null || _c === void 0 ? void 0 : _c.name, providerId].filter(Boolean).join(' - '),
            item_category: 'addon',
            item_category2: undefined,
            item_category3: room.getAddon().name,
            item_category5: ((_d = this.hotel) === null || _d === void 0 ? void 0 : _d.name) + ' Addon',
            item_list_name: this.itemListName,
            coupon: undefined,
            discount: 0,
            index: listPosition || 0,
            price,
            quantity: room.getQuantity() || 1,
            selected_dates: undefined,
            upgrade: undefined,
            upgrade_price_dif: undefined,
        };
    }
    generateRoomImpressionMessageObject(impressions) {
        return {
            event: 'view_item_list',
            currency: this.currency.original,
            ecommerce: {
                items: impressions.map((item, index) => {
                    const { room, rate, quantity, promoCode, dateRange } = item;
                    return this.generateRoomRateProductInfo(room, dateRange, rate, index, quantity, promoCode);
                }),
            },
        };
    }
    generateProductClickMessageObject(product) {
        return {
            event: 'select_item',
            ecommerce: {
                currency: this.currency.original,
                item_list_name: this.itemListName,
                items: [this.generateRoomRateProductInfo(product.room, product.dateRange, undefined, undefined, product.quantity, product.promoCode)],
            },
        };
    }
    generateDateSelectionMessageObject(dateRange, adults, children, infants) {
        return {
            event: 'select_dates',
            ecommerce: {
                currency: this.currency.original,
                arrival_date: dateRange.from.format(DATALAYER_DATE_FORMAT),
                departure_date: dateRange.to.format(DATALAYER_DATE_FORMAT),
                adult_count: adults,
                child_count: children,
                infant_count: infants || 0,
            },
        };
    }
    generateAddToCartMessageObject(product) {
        return {
            event: 'add_to_cart',
            ecommerce: {
                currency: this.currency.original,
                items: [this.generateRoomRateProductInfo(product.room, product.dateRange, product.rate, undefined, product.quantity, product.promoCode)],
            },
        };
    }
    generateAddonsAddToCartMessageObject(product) {
        return {
            event: 'add_to_cart',
            ecommerce: {
                currencyCode: this.currency.original,
                items: [this.generateAddonProductInfo(product.basketAddonRow)],
            },
        };
    }
    generateUpsellConfirmedMessageObject(oldProduct, newProduct) {
        return {
            event: 'upsell_confirmed',
            ecommerce: {
                currency: this.currency.original,
                items: {
                    old: this.generateRoomRateProductInfo(oldProduct.room, oldProduct.dateRange, oldProduct.rate, undefined, oldProduct.quantity, oldProduct.promoCode),
                    new: this.generateRoomRateProductInfo(newProduct.room, newProduct.dateRange, newProduct.rate, undefined, newProduct.quantity, newProduct.promoCode, {
                        upsell: { originalRoomRate: oldProduct.rate },
                    }),
                },
            },
        };
    }
    generateUpsellCancelledMessageObject(product) {
        return {
            event: 'upsell_cancelled',
            ecommerce: {
                currency: this.currency.original,
                items: [this.generateRoomRateProductInfo(product.room, product.dateRange, product.rate, undefined, product.quantity, product.promoCode)],
            },
        };
    }
    generateCheckoutViewMessageObject(basketRows, addonRows) {
        const productItems = basketRows.map((row, index) => {
            var _a;
            return this.generateRoomRateProductInfo(row.getRoom(), { to: row.getStartDate(), from: row.getEndDate() }, (_a = row.getRate()) !== null && _a !== void 0 ? _a : undefined, index, 1, row.getPromoCode(), {
                upsell: { originalRoomRate: row.getPreUpsellRoomRate() },
            });
        });
        addonRows === null || addonRows === void 0 ? void 0 : addonRows.forEach((row, index) => {
            productItems.push(this.generateAddonProductInfo(row, index));
        });
        return {
            event: 'begin_checkout',
            ecommerce: {
                currency: this.currency.original,
                items: productItems,
                page_type: 'conversionintent',
            },
        };
    }
    generateRoomPurchaseMessageObject(basketRows, addonRows, reservations) {
        var _a, _b;
        const productItems = basketRows.map((row, index) => {
            var _a, _b;
            return this.generateRoomRateProductInfo(row.getRoom(), { to: row.getStartDate(), from: row.getEndDate() }, (_a = row.getRate()) !== null && _a !== void 0 ? _a : undefined, index, 1, (_b = row.getRate()) === null || _b === void 0 ? void 0 : _b.promoCode, {
                upsell: { originalRoomRate: row.getPreUpsellRoomRate() },
            });
        });
        addonRows === null || addonRows === void 0 ? void 0 : addonRows.forEach((row, index) => {
            productItems.push(this.generateAddonProductInfo(row, index));
        });
        const guest = (_a = reservations.reservations[0]) === null || _a === void 0 ? void 0 : _a.guest;
        return [
            {
                event: 'purchase',
                ecommerce: {
                    currency: this.currency.original,
                    transaction_id: reservations.itineraryNumber,
                    value: (_b = reservations === null || reservations === void 0 ? void 0 : reservations.total) === null || _b === void 0 ? void 0 : _b.afterTax,
                    tax: 0,
                    coupon: undefined,
                    payment_type: reservations.reservations[0].paymentMethod,
                    page_type: 'conversion',
                    items: productItems,
                },
                user_data: {
                    email: guest === null || guest === void 0 ? void 0 : guest.email,
                    phone_number: (guest === null || guest === void 0 ? void 0 : guest.phone) ? `+${guest.phone}` : undefined,
                    first_name: guest === null || guest === void 0 ? void 0 : guest.firstName,
                    last_name: guest === null || guest === void 0 ? void 0 : guest.lastName,
                },
            },
        ];
    }
    generateRefundMessageObject(reservation) {
        var _a, _b, _c, _d, _e;
        const providerId = (_a = this.hotel) === null || _a === void 0 ? void 0 : _a.providerHotelID;
        const nightKeys = Object.keys(reservation.nights);
        const startDate = (0, dayjs_1.default)(nightKeys[0]);
        const endDate = (0, dayjs_1.default)(nightKeys[nightKeys.length - 1]);
        const discount = nightKeys.reduce((acc, key) => {
            return acc + Number(reservation.nights[key].discount);
        });
        const idParts = [providerId, reservation.roomCode, reservation.rate];
        return {
            event: 'refund',
            ecommerce: {
                currency: this.currency.original,
                transaction_id: reservation.reservationNumber,
                value: reservation.total.afterTax,
                items: [
                    {
                        item_name: ((_b = this.company) === null || _b === void 0 ? void 0 : _b.brandSuffix) + ' Accommodation',
                        item_id: idParts.join('-'),
                        item_brand: [(_c = this.hotel) === null || _c === void 0 ? void 0 : _c.name, providerId].filter(Boolean).join(' - '),
                        item_category: 'Room',
                        item_category2: reservation.rate,
                        item_category3: reservation.roomType,
                        item_category5: ((_d = this.hotel) === null || _d === void 0 ? void 0 : _d.name) + ' Room',
                        item_list_name: this.itemListName,
                        coupon: undefined,
                        discount,
                        index: 0,
                        price: reservation.total.afterTax,
                        quantity: 1,
                        selected_dates: (_e = this.formatDateRange({ from: startDate, to: endDate })) !== null && _e !== void 0 ? _e : undefined,
                        upgrade: undefined,
                        upgrade_price_dif: undefined,
                    },
                ],
            },
        };
    }
}
const ga4 = new GoogleAnalytics4();
exports.GoogleAnalytics4 = ga4;
//# sourceMappingURL=GoogleAnalytics4.js.map