"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BookingWizardHotelSelector = void 0;
const ui_1 = require("@roomstay/ui");
const classnames_1 = __importDefault(require("classnames"));
const react_1 = __importStar(require("react"));
const react_i18next_1 = require("react-i18next");
const AutoAutoHeight_1 = __importDefault(require("../../../../animations/AutoAutoHeight"));
const BookingAPI_1 = __importDefault(require("../../../../api/BookingAPI"));
const Text_1 = __importStar(require("../../Text"));
const Translation_1 = require("../../../../translations/Translation");
const Color_1 = require("../../../../util/Color");
const Select_1 = require("../../Select/Select");
const BookingWizard_1 = require("../BookingWizard");
const BookingWizard_module_scss_1 = __importDefault(require("../BookingWizard.module.scss"));
const BookingWizardBottomSheet_1 = __importStar(require("../BookingWizardBottomSheet/BookingWizardBottomSheet"));
const BookingWizardContent_1 = require("../BookingWizardContent");
const BookingWizardContext_1 = require("../BookingWizardContext");
const BookingWizardHotelSelector_module_scss_1 = __importDefault(require("./BookingWizardHotelSelector.module.scss"));
const BookingWizardHotelSelector = (props) => {
    const { overlay, type, layout, isSmallContainer, stateSections, isImagesTheme, isImagesThemeMobile, onNextHandler } = (0, BookingWizardContext_1.useBookingWizard)();
    const { t } = (0, react_i18next_1.useTranslation)();
    const [open, setOpen] = (0, react_1.useState)(false);
    const [isOnlyProperty, setIsOnlyProperty] = (0, react_1.useState)(false);
    const [finalProperties, setFinalProperties] = (0, react_1.useState)({});
    const { selectedProperty, properties, contentClassName, followElement, searchConfig } = props;
    const unGrouped = t(Translation_1.Translation.Misc.Ungrouped);
    (0, react_1.useEffect)(() => {
        if (stateSections && stateSections[BookingWizard_1.EBookingWizardSection.Property]) {
            setOpen(stateSections[BookingWizard_1.EBookingWizardSection.Property].opening);
        }
    }, [stateSections]);
    function getBookingWizardRegions(properties) {
        return Array.from(new Set(properties.map((p) => p.bookingWizardRegion)));
    }
    const combineAddress = (address) => {
        if (searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.combineAddress) {
            return searchConfig.combineAddress(address);
        }
        const format = (vals) => vals.filter((v) => v && v !== '0').join(', ');
        return [format([address === null || address === void 0 ? void 0 : address.line1, address === null || address === void 0 ? void 0 : address.city]), format([address === null || address === void 0 ? void 0 : address.postalCode, address === null || address === void 0 ? void 0 : address.state])].filter(Boolean).join(', ');
    };
    const fetchPropertyData = () => __awaiter(void 0, void 0, void 0, function* () {
        if (!(searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.companyId)) {
            setFinalProperties(properties);
            return;
        }
        const fetchedData = yield BookingAPI_1.default.Hotel.fetchBookingWizardData(searchConfig.companyId);
        const regions = getBookingWizardRegions(fetchedData);
        let tmpFinalProperties = {};
        if (regions.length > 1) {
            // Build lookup for client properties
            const clientMap = Object.fromEntries(Object.values(properties)
                .flat()
                .map((p) => [p.id, p]));
            // Group by API-provided regions
            for (const region of regions) {
                const matches = fetchedData
                    .filter((fp) => fp.bookingWizardRegion === region)
                    .map((fp) => {
                    var _a;
                    const clientProp = clientMap[fp.id];
                    if (!clientProp)
                        return null;
                    return Object.assign(Object.assign({}, clientProp), { name: fp.name, address: fp.address, card: {
                            image: ((_a = clientProp.card) === null || _a === void 0 ? void 0 : _a.image) || fp.logo,
                            text: combineAddress(fp.address),
                        } });
                })
                    .filter(Boolean);
                if (matches.length > 0) {
                    tmpFinalProperties[region || unGrouped] = matches;
                }
            }
        }
        else {
            const fetchedDataMap = Object.fromEntries(fetchedData.map((p) => [p.id, p]));
            // Fallback: enrich clientProperties with address
            for (const [region, hotels] of Object.entries(properties)) {
                tmpFinalProperties[region] = hotels.map((hotel) => {
                    var _a, _b, _c;
                    return (Object.assign(Object.assign({}, hotel), { address: (_a = fetchedDataMap[hotel.id]) === null || _a === void 0 ? void 0 : _a.address, card: {
                            image: (_b = hotel.card) === null || _b === void 0 ? void 0 : _b.image,
                            text: combineAddress((_c = fetchedDataMap[hotel.id]) === null || _c === void 0 ? void 0 : _c.address),
                        } }));
                });
            }
        }
        if (searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.sortCompareFn) {
            // Use custom comparator
            tmpFinalProperties = Object.fromEntries(Object.entries(tmpFinalProperties)
                .sort(([a], [b]) => searchConfig.sortCompareFn(a, b)) // Sort regions
                .map(([region, props]) => [region, props.sort((p1, p2) => searchConfig.sortCompareFn(p1, p2))]) // Sort properties
            );
        }
        else {
            // Default: Sort regions alphabetically, move unGrouped to the end,
            // and also sort properties by name inside each region
            tmpFinalProperties = Object.fromEntries(Object.entries(tmpFinalProperties)
                .sort(([a], [b]) => {
                if (a === unGrouped)
                    return 1;
                if (b === unGrouped)
                    return -1;
                return a.localeCompare(b);
            })
                .map(([region, props]) => [region, props.sort((p1, p2) => p1.name.localeCompare(p2.name))]));
        }
        setFinalProperties(tmpFinalProperties);
    });
    (0, react_1.useEffect)(() => {
        fetchPropertyData();
    }, [searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.companyId]);
    const searchFilter = (bwProperties, searchQuery) => {
        var _a, _b;
        if (searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchFilter) {
            // Use custom search
            return searchConfig.searchFilter(bwProperties, searchQuery);
        }
        // Default search
        const query = ((_a = searchQuery === null || searchQuery === void 0 ? void 0 : searchQuery.trim()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
        if (!query || (query && selectedProperty && query === ((_b = selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.name) === null || _b === void 0 ? void 0 : _b.toLowerCase()))) {
            return bwProperties;
        }
        const filtered = {};
        for (const [region, hotels] of Object.entries(bwProperties)) {
            const matches = hotels.filter((hotel) => {
                if (!hotel)
                    return false;
                const { city = '', state = '' } = (hotel === null || hotel === void 0 ? void 0 : hotel.address) || {};
                const keywords = [hotel.name, region, city, state].filter(Boolean).map((kw) => kw.toLowerCase());
                return keywords.some((kw) => kw.includes(query));
            });
            if (matches.length > 0) {
                filtered[region] = matches;
            }
        }
        return filtered;
    };
    const optionedProperties = (0, react_1.useMemo)(() => {
        let isOnly = false;
        const options = [];
        const filteredProperties = searchFilter(finalProperties, searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchQuery);
        // Here we group each key as a new TOption Group to order hotels better.
        const propertyKeys = Object.keys(filteredProperties);
        if (propertyKeys.length > 1) {
            propertyKeys.forEach((propertyKey) => {
                var _a;
                const option = {
                    name: propertyKey,
                    id: '',
                    options: [],
                    colors: {},
                };
                for (const property of filteredProperties[propertyKey]) {
                    (_a = option.options) === null || _a === void 0 ? void 0 : _a.push(property);
                }
                options.push(option);
            });
        }
        else if (propertyKeys.length === 1) {
            filteredProperties[propertyKeys[0]].forEach((option) => {
                options.push(option);
            });
            if (filteredProperties[propertyKeys[0]].length == 1 && filteredProperties[propertyKeys[0]][0].id === (selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.id)) {
                isOnly = true;
            }
        }
        setIsOnlyProperty(isOnly);
        return options;
    }, [properties, searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchQuery, finalProperties]);
    const onPropertyClick = (property) => {
        var _a;
        (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, property);
        searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.setSearchQuery((property === null || property === void 0 ? void 0 : property.name) || '');
        if (!isImagesThemeMobile) {
            setOpen(false);
        }
    };
    const onClearAllHandler = (event) => {
        var _a;
        (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props);
        searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.setSearchQuery('');
        event === null || event === void 0 ? void 0 : event.preventDefault();
        event === null || event === void 0 ? void 0 : event.stopPropagation();
    };
    const getOption = (key) => {
        const indexes = Object.keys(properties);
        for (const index of indexes) {
            for (const property of properties[index]) {
                if (key === property.id) {
                    return property;
                }
            }
        }
    };
    const renderOptions = () => {
        const filteredProperties = searchFilter(finalProperties, searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchQuery);
        const indexes = Object.keys(filteredProperties);
        if (indexes.length > 1) {
            return indexes.map((indexName) => renderGroup(indexName, filteredProperties[indexName]));
        }
        else if (indexes.length === 1) {
            return filteredProperties[indexes[0]].map((property) => renderOption(property));
        }
    };
    const renderGroup = (name, options) => {
        return (react_1.default.createElement("div", { key: name },
            react_1.default.createElement("div", { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['container--suggest-list-hotel'], BookingWizardHotelSelector_module_scss_1.default['--group-title']) },
                react_1.default.createElement(Text_1.default, { type: Text_1.TextType.Small, color: Color_1.Color.DarkGrey }, name)),
            options.map((option) => renderOption(option))));
    };
    const renderOption = (property) => {
        var _a, _b;
        if (isImagesTheme) {
            return (react_1.default.createElement("div", { key: property.id, className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['card'], { [BookingWizardHotelSelector_module_scss_1.default['--selected']]: (selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.id) === property.id }), onClick: () => onPropertyClick(property) },
                react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['card-img'] },
                    react_1.default.createElement("img", { src: (_a = property === null || property === void 0 ? void 0 : property.card) === null || _a === void 0 ? void 0 : _a.image })),
                react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['card-body'] },
                    react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['card-title'] }, property.name),
                    react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['card-sub-title'] }, (_b = property === null || property === void 0 ? void 0 : property.card) === null || _b === void 0 ? void 0 : _b.text))));
        }
        else {
            return (react_1.default.createElement("div", { key: property.id, className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['container--suggest-list-hotel'], { [BookingWizardHotelSelector_module_scss_1.default['--selected']]: (selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.id) === property.id }), onClick: () => onPropertyClick(property) },
                react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['container--suggest-list-hotel-name'] }, property.name),
                react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default.check })));
        }
    };
    const onOpenDrawer = () => {
        setOpen(true);
    };
    if (isOnlyProperty && !searchConfig) {
        return react_1.default.createElement(Text_1.default, null, selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.name);
    }
    if (type === 'inline') {
        return (react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['inline-container'] },
            react_1.default.createElement(AutoAutoHeight_1.default, { open: open },
                react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default['inline-box'] }, renderOptions()))));
    }
    if (type === 'bottom-sheet') {
        const ItemDisplay = () => {
            return (react_1.default.createElement("div", { className: (0, classnames_1.default)({
                    [BookingWizardHotelSelector_module_scss_1.default['--mini']]: !isImagesThemeMobile && layout === 'horizontal-condensed',
                    [BookingWizardHotelSelector_module_scss_1.default['item-display']]: isImagesThemeMobile || !!searchConfig,
                    [BookingWizardHotelSelector_module_scss_1.default['--searchable']]: !!searchConfig,
                }), onClick: onOpenDrawer },
                react_1.default.createElement(Text_1.default, { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default.optionLabel, {
                        [BookingWizardHotelSelector_module_scss_1.default.placeholder]: !(selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.name),
                        [BookingWizardHotelSelector_module_scss_1.default['text-ellipsis-with-icon']]: !!searchConfig,
                    }), bold: true }, (selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.name) || t(Translation_1.Translation.Misc.PleaseSelectHotelMobile)),
                isImagesThemeMobile && !searchConfig ? react_1.default.createElement(ui_1.Icon, { icon: ui_1.IconType.Dropdown }) : null,
                searchConfig && react_1.default.createElement(BookingWizardContent_1.BWClearButton, { show: !!searchConfig.searchQuery, onClick: onClearAllHandler, hasLabel: true, hasSearchInput: true }),
                searchConfig && react_1.default.createElement(BookingWizardContent_1.BWSearchButton, { show: !searchConfig.searchQuery, hasLabel: true, hasSearchInput: true })));
        };
        return (react_1.default.createElement("div", { className: (0, classnames_1.default)({
                [BookingWizardHotelSelector_module_scss_1.default['container-searchable']]: !!searchConfig,
            }) },
            react_1.default.createElement(ItemDisplay, null),
            react_1.default.createElement(BookingWizardBottomSheet_1.default, Object.assign({ className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default.container, BookingWizardHotelSelector_module_scss_1.default['--bottom-sheet'], {
                    [BookingWizardHotelSelector_module_scss_1.default['custom-overlay-images-theme']]: isImagesTheme,
                }), open: open, onDismiss: () => {
                    if (!isImagesThemeMobile) {
                        setOpen(false);
                    }
                }, header: react_1.default.createElement(react_1.default.Fragment, null,
                    react_1.default.createElement(BookingWizardBottomSheet_1.BWBottomSheetHeader, { title: t(Translation_1.Translation.Misc.ChooseHotelMobile), onClose: () => setOpen(false) }),
                    searchConfig && (react_1.default.createElement("div", { className: BookingWizardHotelSelector_module_scss_1.default.header },
                        react_1.default.createElement(SelectorSearchBox, { option: selectedProperty, searchConfig: searchConfig, onClearAllHandler: onClearAllHandler })))), footer: react_1.default.createElement(BookingWizardBottomSheet_1.BWBottomSheetFooter, { hidePrev: stateSections[BookingWizard_1.EBookingWizardSection.Property].isFirst, onNext: () => onNextHandler(BookingWizard_1.EBookingWizardSection.Property), disabledNext: !selectedProperty }) }, (searchConfig
                ? {
                    snapPoints: () => [window.innerHeight],
                    defaultSnap: ({ maxHeight }) => maxHeight,
                }
                : {})),
                react_1.default.createElement("div", { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default.content, contentClassName) }, renderOptions() || react_1.default.createElement(Text_1.default, { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['input-no-options']) }, t(Translation_1.Translation.Misc.EmptySearchHotel))))));
    }
    return (react_1.default.createElement("div", { className: (0, classnames_1.default)({ [BookingWizardHotelSelector_module_scss_1.default['--mini']]: layout === 'horizontal-condensed' }) },
        react_1.default.createElement(Select_1.Select, { target: followElement, offset: overlay === null || overlay === void 0 ? void 0 : overlay.offset, options: optionedProperties, value: selectedProperty === null || selectedProperty === void 0 ? void 0 : selectedProperty.id, onChange: (value) => onPropertyClick(getOption(value)), keyName: "id", labelName: "name", hideExpandIcon: layout === 'horizontal-condensed' || !!searchConfig, disableNative: true, overlay: {
                containerClassName: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['custom-overlay'], {
                    [BookingWizardHotelSelector_module_scss_1.default['small-container']]: isSmallContainer,
                    [BookingWizardHotelSelector_module_scss_1.default['custom-overlay-images-theme']]: isImagesTheme,
                }),
                strategy: 'absolute',
                usePortal: false,
                placement: (overlay === null || overlay === void 0 ? void 0 : overlay.placement) || 'bottom',
                fallbackPlacements: (overlay === null || overlay === void 0 ? void 0 : overlay.fallbackPlacements) || 'bottom',
                hideStyles: true,
            }, renderOption: (property) => {
                if (property)
                    return renderOption(property);
                return null;
            }, renderLabel: (option) => react_1.default.createElement(SelectorSearchBox, { option: option, searchConfig: searchConfig, onClearAllHandler: onClearAllHandler }), renderNoOptions: (targetRef) => {
                var _a;
                const width = (_a = targetRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth;
                return (react_1.default.createElement(Text_1.default, { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['input-no-options']), style: {
                        width: width,
                    } }, t(Translation_1.Translation.Misc.EmptySearchHotel)));
            }, open: searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.focused })));
};
exports.BookingWizardHotelSelector = BookingWizardHotelSelector;
const SelectorSearchBox = ({ option, searchConfig, onClearAllHandler, }) => {
    const { t } = (0, react_i18next_1.useTranslation)();
    (0, react_1.useEffect)(() => {
        if ((searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchQuery.trim()) === '') {
            onClearAllHandler();
        }
    }, [searchConfig === null || searchConfig === void 0 ? void 0 : searchConfig.searchQuery]);
    if (!searchConfig) {
        return (react_1.default.createElement(Text_1.default, { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default.optionLabel, BookingWizard_module_scss_1.default['value']), bold: true }, (option === null || option === void 0 ? void 0 : option.name) || react_1.default.createElement("span", { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['hotel-dropdown-label'], BookingWizard_module_scss_1.default['value']) }, t(Translation_1.Translation.Misc.PleaseSelectHotel))));
    }
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("input", { className: (0, classnames_1.default)(BookingWizardHotelSelector_module_scss_1.default['input-search'], BookingWizard_module_scss_1.default['text-ellipsis-with-icon'], BookingWizard_module_scss_1.default['value']), type: "text", value: searchConfig.searchQuery || (option === null || option === void 0 ? void 0 : option.name) || '', placeholder: t(Translation_1.Translation.Misc.PleaseSelectHotel), onChange: (e) => searchConfig.setSearchQuery(e.target.value), autoComplete: "off" }),
        searchConfig && react_1.default.createElement(BookingWizardContent_1.BWClearButton, { show: !!searchConfig.searchQuery, onClick: onClearAllHandler, hasLabel: true, hasSearchInput: true }),
        searchConfig && react_1.default.createElement(BookingWizardContent_1.BWSearchButton, { show: !searchConfig.searchQuery, hasLabel: true, hasSearchInput: true })));
};
//# sourceMappingURL=BookingWizardHotelSelector.js.map