import { a as __awaiter } from './tslib.es6-ab63fd84.js';
import React__default, { useMemo, useEffect, useRef, useCallback, useState, useReducer } from 'react';
import { Global, css } from '@emotion/react';
import { S as StyledLocationResultsWrapper, a as StyledLocationResultsList, b as StyledLiSkeleton, c as StyledLocationItem, d as StyledPinIcon, M as MagnifierIcon, C as CloseIcon, e as ClearIcon, P as PinIcon, D as DefaultThumbnailAny, f as DefaultThumbnailDoctor, g as DefaultThumbnailService, h as getApiPath, u as useGeolocation } from './utils-a34a4457.js';
import { u as useTranslations } from './index-960c3169.js';
import debounce from 'lodash/debounce';
import { I as ID_OPTION_ALL_LOCATION, L as LOCALIZED_SLUGS, a as ID_OPTION_CURRENT_LOCATION } from './constants-106f2bcb.js';
import styled from '@emotion/styled';
import { I as Input } from './index-d9b5d0ac.js';
import { T as Text } from './index-d0a1200e.js';
import { theme } from './miscTheme.js';
import shuffle from 'lodash/shuffle';
import { a as useOutsideClick } from './useOutsideClick-10e74687.js';
import { M as MediaQueries } from './utils-32d7d5af.js';
import Skeleton from 'react-loading-skeleton';
import { P as PATHS } from './paths-b9ad10a5.js';
import './index-a8162282.js';
import 'date-fns/locale';
import './index-91c6a49c.js';
import './Locale-87b46912.js';
import './constantsSite.js';
import './constantsDomainLocales.js';
import './constantsRiskScreener.js';
import './constantsIsProduction.js';
import './miscCookieHelper.js';
import 'string-format';
import './translationsContext-4de1415e.js';
import '@mantine/core';
import './index-38e03570.js';

const StyledSearchBarWrapper = styled.div ``;
const StyledSearchBarMobileWrapper = styled.div `
  --searchbar-z-index: 305;
  &[data-is-modal='true'] {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    height: var(--mobile-care-searchbar-height, 100%);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background-color: white;
    z-index: var(--searchbar-z-index);
  }
`;
const StyledSearchBarMobileModalHeader = styled.section ``;
const StyledHiddenInputMobile = styled.input `
  position: fixed;
  left: -100%;
  top: -100%;
`;
const StyledInput = styled(Input) `
  #booking-search-bar & {
    input {
      font-size: 16px;
    }
  }
`;

const LocationResults = ({ cities, isLoading, onLocationClick, selectedLocation, }) => {
    const { t, locale } = useTranslations();
    const renderContent = () => {
        if (isLoading) {
            return React__default.createElement(StyledLiSkeleton, { count: 5 });
        }
        if (!cities || cities.length < 1) {
            return (React__default.createElement(React__default.Fragment, null,
                React__default.createElement(StyledLocationItem, { "data-is-denied": "true" },
                    React__default.createElement(Text, { size: "sm", color: "#ccc" }, t('booking.searchBar.noResults')))));
        }
        return (React__default.createElement(React__default.Fragment, null,
            React__default.createElement(StyledLocationItem, { key: "all-location", role: "button", tabIndex: 0, onClick: () => {
                    var _a;
                    if (onLocationClick) {
                        onLocationClick({
                            name: t('booking.searchBar.allLocations'),
                            id: ID_OPTION_ALL_LOCATION,
                            slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
                        });
                    }
                } },
                React__default.createElement(StyledPinIcon, { color: theme.colors.neutral400 }),
                React__default.createElement(Text, { size: "md" }, t('booking.searchBar.allLocations'))),
            cities.map((city) => (React__default.createElement(StyledLocationItem, { key: city.id, onClick: (evt) => {
                    evt.nativeEvent.stopImmediatePropagation();
                    if (onLocationClick) {
                        onLocationClick(city);
                    }
                }, role: "button", tabIndex: 0, "aria-label": `Select ${city.name} as location`, isSelected: (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === city.id },
                React__default.createElement(StyledPinIcon, { color: theme.colors.neutral400 }),
                React__default.createElement(Text, { size: "md" }, city.name))))));
    };
    return (React__default.createElement(StyledLocationResultsWrapper, { "data-testid": "location-search-results" },
        React__default.createElement(StyledLocationResultsList, null, renderContent())));
};

const EVENT_NAMES = {
    TYPE_CHARACTER: 'TYPE_CHARACTER',
    REMOVE_CHARACTER: 'REMOVE_CHARACTER',
    REMOVE_ALL: 'REMOVE_ALL',
    REMOVE_LAST_VISIBLE_NODE: 'REMOVE_LAST_VISIBLE_NODE',
    PAUSE_FOR: 'PAUSE_FOR',
    CHANGE_DELETE_SPEED: 'CHANGE_DELETE_SPEED',
    CHANGE_DELAY: 'CHANGE_DELAY',
    PASTE_STRING: 'PASTE_STRING',
};
const getRandomInteger = (min, max) => {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};
const VISIBLE_NODE_TYPES = {
    TEXT_NODE: 'TEXT_NODE',
};
class Typewriter {
    constructor(options) {
        this.state = {
            lastFrameTime: null,
            pauseUntil: null,
            eventQueue: [],
            eventLoop: null,
            eventLoopPaused: false,
            reverseCalledEvents: [],
            calledEvents: [],
            visibleNodes: [],
            initialOptions: null,
        };
        this.options = {
            strings: null,
            delay: 'natural',
            pauseFor: 1500,
            deleteSpeed: 'natural',
            loop: false,
            autoStart: false,
            stringSplitter: null,
            onCreateTextNode: null,
            onRemoveNode: null,
        };
        this.start = () => {
            this.state.eventLoopPaused = false;
            this.runEventLoop();
            return this;
        };
        this.pause = () => {
            this.state.eventLoopPaused = true;
            return this;
        };
        this.stop = () => {
            if (this.state.eventLoop) {
                window.cancelAnimationFrame(this.state.eventLoop);
                this.state.eventLoop = null;
            }
            return this;
        };
        this.pauseFor = (ms) => {
            this.addEventToQueue(EVENT_NAMES.PAUSE_FOR, { ms });
            return this;
        };
        this.typeOutAllStrings = () => {
            if (typeof this.options.strings === 'string') {
                this.typeString(this.options.strings).pauseFor(this.options.pauseFor);
                return this;
            }
            this.options.strings.forEach((string) => {
                this.typeString(string)
                    .pauseFor(this.options.pauseFor)
                    .deleteAll(this.options.deleteSpeed);
            });
            return this;
        };
        this.typeString = (string, node = null) => {
            if (string) {
                const { stringSplitter } = this.options || {};
                const characters = typeof stringSplitter === 'function'
                    ? stringSplitter(string)
                    : string.split('');
                this.typeCharacters(characters, node);
            }
            return this;
        };
        this.pasteString = (string, node = null) => {
            if (string) {
                this.addEventToQueue(EVENT_NAMES.PASTE_STRING, {
                    character: string,
                    node,
                });
            }
            return this;
        };
        this.deleteAll = (speed = 'natural') => {
            this.addEventToQueue(EVENT_NAMES.REMOVE_ALL, { speed });
            return this;
        };
        this.changeDeleteSpeed = (speed) => {
            if (!speed) {
                throw new Error('Must provide new delete speed');
            }
            this.addEventToQueue(EVENT_NAMES.CHANGE_DELETE_SPEED, { speed });
            return this;
        };
        this.changeDelay = (delay) => {
            if (!delay) {
                throw new Error('Must provide new delay');
            }
            this.addEventToQueue(EVENT_NAMES.CHANGE_DELAY, { delay });
            return this;
        };
        this.deleteChars = (amount) => {
            if (!amount) {
                throw new Error('Must provide amount of characters to delete');
            }
            for (let i = 0; i < amount; i++) {
                this.addEventToQueue(EVENT_NAMES.REMOVE_CHARACTER);
            }
            return this;
        };
        this.typeCharacters = (characters, node = null) => {
            if (!characters || !Array.isArray(characters)) {
                throw new Error('Characters must be an array');
            }
            characters.forEach((character) => {
                this.addEventToQueue(EVENT_NAMES.TYPE_CHARACTER, { character, node });
            });
            return this;
        };
        this.removeCharacters = (characters) => {
            if (!characters || !Array.isArray(characters)) {
                throw new Error('Characters must be an array');
            }
            characters.forEach(() => {
                this.addEventToQueue(EVENT_NAMES.REMOVE_CHARACTER);
            });
            return this;
        };
        this.addEventToQueue = (eventName, eventArgs, prepend = false) => {
            return this.addEventToStateProperty(eventName, eventArgs, prepend, 'eventQueue');
        };
        this.addReverseCalledEvent = (eventName, eventArgs, prepend = false) => {
            const { loop } = this.options;
            if (!loop) {
                return this;
            }
            return this.addEventToStateProperty(eventName, eventArgs, prepend, 'reverseCalledEvents');
        };
        this.addEventToStateProperty = (eventName, eventArgs, prepend = false, property) => {
            const eventItem = {
                eventName,
                eventArgs: eventArgs || {},
            };
            if (prepend) {
                this.state[property] = [eventItem, ...this.state[property]];
            }
            else {
                this.state[property] = [...this.state[property], eventItem];
            }
            return this;
        };
        this.runEventLoop = () => {
            if (!this.state.lastFrameTime) {
                this.state.lastFrameTime = Date.now();
            }
            // Setup variables to calculate if this frame should run
            const nowTime = Date.now();
            const delta = nowTime - this.state.lastFrameTime;
            if (!this.state.eventQueue.length) {
                if (!this.options.loop) {
                    return;
                }
                // Reset event queue if we are looping
                this.state.eventQueue = [...this.state.calledEvents];
                this.state.calledEvents = [];
                this.options = Object.assign({}, this.state.initialOptions);
            }
            // Request next frame
            this.state.eventLoop = window.requestAnimationFrame(this.runEventLoop);
            // Check if event loop is paused
            if (this.state.eventLoopPaused) {
                return;
            }
            // Check if state has pause until time
            if (this.state.pauseUntil) {
                // Check if event loop should be paused
                if (nowTime < this.state.pauseUntil) {
                    return;
                }
                // Reset pause time
                this.state.pauseUntil = null;
            }
            // Make a clone of event queue
            const eventQueue = [...this.state.eventQueue];
            // Get first event from queue
            const currentEvent = eventQueue.shift();
            // Setup delay variable
            let delay = 0;
            // Check if frame should run or be
            // skipped based on fps interval
            if (currentEvent.eventName === EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE ||
                currentEvent.eventName === EVENT_NAMES.REMOVE_CHARACTER) {
                delay =
                    this.options.deleteSpeed === 'natural'
                        ? getRandomInteger(40, 80)
                        : this.options.deleteSpeed;
            }
            else {
                delay =
                    this.options.delay === 'natural'
                        ? getRandomInteger(120, 160)
                        : this.options.delay;
            }
            if (delta <= delay) {
                return;
            }
            // Get current event args
            const { eventName, eventArgs } = currentEvent;
            // Run item from event loop
            switch (eventName) {
                case EVENT_NAMES.PASTE_STRING:
                case EVENT_NAMES.TYPE_CHARACTER: {
                    const { character } = eventArgs;
                    const textNode = document.createTextNode(character);
                    let textNodeToUse = textNode;
                    if (this.options.onCreateTextNode &&
                        typeof this.options.onCreateTextNode === 'function') {
                        textNodeToUse = this.options.onCreateTextNode(character, textNode);
                    }
                    this.state.visibleNodes = [
                        ...this.state.visibleNodes,
                        {
                            type: VISIBLE_NODE_TYPES.TEXT_NODE,
                            character,
                            node: textNodeToUse,
                        },
                    ];
                    break;
                }
                case EVENT_NAMES.REMOVE_CHARACTER: {
                    eventQueue.unshift({
                        eventName: EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE,
                        eventArgs: { removingCharacterNode: true },
                    });
                    break;
                }
                case EVENT_NAMES.PAUSE_FOR: {
                    const { ms } = currentEvent.eventArgs;
                    this.state.pauseUntil = Date.now() + parseInt(ms);
                    break;
                }
                case EVENT_NAMES.REMOVE_ALL: {
                    const { visibleNodes } = this.state;
                    const { speed } = eventArgs;
                    const removeAllEventItems = [];
                    if (speed) {
                        removeAllEventItems.push({
                            eventName: EVENT_NAMES.CHANGE_DELETE_SPEED,
                            eventArgs: { speed, temp: true },
                        });
                    }
                    for (let i = 0, length = visibleNodes.length; i < length; i++) {
                        removeAllEventItems.push({
                            eventName: EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE,
                            eventArgs: { removingCharacterNode: false },
                        });
                    }
                    if (speed) {
                        removeAllEventItems.push({
                            eventName: EVENT_NAMES.CHANGE_DELETE_SPEED,
                            eventArgs: { speed: this.options.deleteSpeed, temp: true },
                        });
                    }
                    eventQueue.unshift(...removeAllEventItems);
                    break;
                }
                case EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE: {
                    if (this.state.visibleNodes.length) {
                        const { node, character } = this.state.visibleNodes.pop();
                        if (this.options.onRemoveNode &&
                            typeof this.options.onRemoveNode === 'function') {
                            this.options.onRemoveNode({
                                node,
                                character,
                            });
                        }
                        if (node) {
                            node.parentNode.removeChild(node);
                        }
                    }
                    break;
                }
                case EVENT_NAMES.CHANGE_DELETE_SPEED: {
                    this.options.deleteSpeed = currentEvent.eventArgs.speed;
                    break;
                }
                case EVENT_NAMES.CHANGE_DELAY: {
                    this.options.delay = currentEvent.eventArgs.delay;
                    break;
                }
            }
            // Add que item to called queue if we are looping
            if (this.options.loop) {
                if (currentEvent.eventName !== EVENT_NAMES.REMOVE_LAST_VISIBLE_NODE &&
                    !(currentEvent.eventArgs && currentEvent.eventArgs.temp)) {
                    this.state.calledEvents = [...this.state.calledEvents, currentEvent];
                }
            }
            // Replace state event queue with cloned queue
            this.state.eventQueue = eventQueue;
            // Set last frame time so it can be used to calculate next frame
            this.state.lastFrameTime = nowTime;
        };
        if (options) {
            this.options = Object.assign(Object.assign({}, this.options), options);
        }
        this.state.initialOptions = Object.assign({}, this.options);
        this.init();
    }
    init() {
        this.addEventToQueue(EVENT_NAMES.REMOVE_ALL, null, true);
        if (this.options.autoStart === true && this.options.strings) {
            this.typeOutAllStrings().start();
        }
    }
}

function useAnimatedPlaceholder({ inputRef, wrapperRef, disabled, }) {
    const { t, locale } = useTranslations();
    const values = useMemo(() => {
        if (disabled) {
            return [];
        }
        const shuffleKeys = [
            'booking.searchBar.placeholder.hospital',
            'booking.searchBar.placeholder.doctor',
        ];
        if (locale !== 'zh-TW') {
            shuffleKeys.push('booking.searchBar.placeholder.specialty', 'booking.searchBar.placeholder.service');
        }
        return shuffle(shuffleKeys).map((s) => t(s));
    }, [t, locale]);
    useEffect(() => {
        if (disabled) {
            return;
        }
        const input = getInput();
        if (input) {
            input.placeholder = '';
            new Typewriter({
                strings: values,
                autoStart: true,
                loop: true,
                delay: 32,
                deleteSpeed: 32,
                pauseFor: 1500,
                onCreateTextNode: customNodeCreator,
                onRemoveNode: onRemoveNode,
            });
        }
    }, [inputRef, wrapperRef]);
    function customNodeCreator(character) {
        const input = getInput();
        if (input) {
            input.placeholder = input.placeholder + character;
        }
        return null;
    }
    function onRemoveNode() {
        const input = getInput();
        if (input) {
            input.placeholder = input.placeholder.slice(0, -1);
        }
    }
    function getInput() {
        if (inputRef && inputRef.current) {
            return inputRef.current;
        }
        else if (wrapperRef && wrapperRef.current) {
            return wrapperRef.current.querySelector('input') || null;
        }
        return null;
    }
    return;
}

const StyledFakeInputSearchMobile = styled.div `
  user-select: none;
  input {
    pointer-events: none;
    background-color: white;
  }
`;
function MobileFakeInput({ focused, value = '', onClick, trackingAttributes, inputSearchPlaceholder, }) {
    const { t } = useTranslations();
    const wrapperRef = useRef(null);
    useAnimatedPlaceholder({ wrapperRef, disabled: !!inputSearchPlaceholder });
    const gaAttributes = useMemo(() => {
        if (trackingAttributes) {
            return {
                'data-event-category': trackingAttributes.dataEventCategory,
                'data-event-action': trackingAttributes.dataEventAction,
                'data-event-label': trackingAttributes.dataEventLabel,
            };
        }
        else {
            return {};
        }
    }, [trackingAttributes]);
    return (React__default.createElement(StyledFakeInputSearchMobile, Object.assign({ onClick: () => onClick && onClick(), ref: wrapperRef }, gaAttributes),
        React__default.createElement(StyledInput, { inputClassName: focused === 'location' ? 'focused' : undefined, name: "booking-search-placeholder", displayIcon: React__default.createElement(MagnifierIcon, { color: theme.colors.gray400 }), placeholder: t('booking.searchBar.searchInput.placeholder'), value: value, size: "md" })));
}

const StyledTopBar = styled.header `
  display: flex;
  height: 64px;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
  position: sticky;
  z-index: 99;
  background-color: white;
  top: 0;
  left: 0;
`;
const StyledTopBarHeaderRight = styled.div `
  display: inline-flex;
  flex: 1;
  justify-content: flex-end;
  cursor: pointer;
  text-decoration: underline;
`;
const StyledTopBarIcon = styled.div `
  display: flex;
  align-items: center;
  margin-left: 16px;
  cursor: pointer;
`;
const StyledTopbarHeading = styled.div `
  width: 100%;
  margin-left: 24px;
`;
const StyledTopbarHeadingText = styled(Text) `
  color: ${theme.colors.secondaryDark};
  text-align: start;
`;

const MobileTopBar = ({ className, onLeftClick, headingText, onRightClick, iconLeft, textRight, }) => {
    return (React__default.createElement(StyledTopBar, { className: className },
        React__default.createElement(StyledTopBarIcon, { onClick: onLeftClick }, iconLeft || React__default.createElement(CloseIcon, { color: theme.colors.gray800 })),
        React__default.createElement(StyledTopbarHeading, null,
            React__default.createElement(StyledTopbarHeadingText, { size: "md", weight: "bold" }, headingText)),
        React__default.createElement(StyledTopBarHeaderRight, { onClick: onRightClick }, textRight && React__default.createElement("p", null, textRight))));
};

const SEARCH_KEYWORD_MIN_LENGTH = {
    'en-PH': 3,
    'tl-PH': 2,
    'id-ID': 3,
    'vi-VN': 2,
    'zh-TW': 0,
    'ms-MY': 2,
    'th-TH': 2,
};

const initialState = {
    isMobile: false,
    isDebug: false,
    navigateTo: null,
    geoLocationPermission: 'unset',
    geoLocationCoordinates: null,
    focused: 'none',
    searchLocationKeywords: '',
    searchKeywords: '',
    selectedLocation: null,
    defaultCity: null,
    initialCities: [],
    cities: [],
    searchResults: [],
    initialSearchResults: [],
    isLoadingCities: false,
    isLoadingSearchResults: false,
    isMobileModalOpened: false,
    initialSelectedCity: null,
    autoCompleteDisabled: false,
    inputSearchPlaceholder: '',
    locale: 'vi-VN',
};
var ActionTypes;
(function (ActionTypes) {
    ActionTypes["NavigateTo"] = "navigate to url";
    ActionTypes["ClickOutsideInputLocation"] = "click outside input location";
    ActionTypes["ClickOutsideInputSearch"] = "click outside input search";
    ActionTypes["SelectCurrentLocation"] = "select current location";
    ActionTypes["FocusInputLocation"] = "focus input location";
    ActionTypes["FocusInputSearch"] = "focus input search";
    ActionTypes["ChangeInputLocation"] = "change input location";
    ActionTypes["ChangeInputSearch"] = "change input search";
    ActionTypes["ClearInputLocation"] = "clear input location";
    ActionTypes["ClearInputSearch"] = "clear input search";
    ActionTypes["SelectLocation"] = "select location";
    ActionTypes["FetchCitiesStart"] = "fetch cities start";
    ActionTypes["FetchCitiesFinish"] = "fetch cities finish";
    ActionTypes["FetchSearchResultsStart"] = "fetch search results start";
    ActionTypes["FetchSearchResultsComplete"] = "fetch search results complete";
    ActionTypes["FetchSearchResultsFinish"] = "fetch search results finish";
    ActionTypes["FetchCitiesByGeoIpComplete"] = "fetch cities by geo IP finish";
    ActionTypes["FetchCitiesByKeywordComplete"] = "fetch cities by keyword finish";
    ActionTypes["DisplayInitialCities"] = "display initial cities";
    ActionTypes["DisplayInitialSearchResults"] = "display initial search results";
    ActionTypes["GrantGeoLocationPermission"] = "grant geolocation permission";
    ActionTypes["DenyGeoLocationPermission"] = "deny geolocation permission";
    ActionTypes["OpenMobileModal"] = "open mobile modal";
    ActionTypes["CloseMobileModal"] = "close mobile modal";
    ActionTypes["UpdateInitialSearchValue"] = "update initial search value";
    ActionTypes["SelectSearchResult"] = "select search result";
    ActionTypes["SetInputSearchPlaceholder"] = "set input search placeholder";
})(ActionTypes || (ActionTypes = {}));
function resetSearchLocationKeywords(state) {
    const { selectedLocation, searchLocationKeywords } = state;
    if (selectedLocation && searchLocationKeywords !== selectedLocation.name) {
        return Object.assign(Object.assign({}, state), { searchLocationKeywords: selectedLocation.name });
    }
    return state;
}
function reducer(state, action) {
    var _a;
    if (state.isDebug) {
        console.log('bookingSearchBar', { action, state });
    }
    switch (action.type) {
        case ActionTypes.NavigateTo:
            return Object.assign(Object.assign({}, state), { navigateTo: action.payload, focused: 'none', isMobileModalOpened: false });
        case ActionTypes.ClickOutsideInputLocation: {
            if (state.isMobile || state.focused !== 'location') {
                return state;
            }
            return resetSearchLocationKeywords(Object.assign(Object.assign({}, state), { focused: 'none' }));
        }
        case ActionTypes.ClickOutsideInputSearch: {
            if (state.isMobile || state.focused !== 'search') {
                return state;
            }
            return Object.assign(Object.assign({}, state), { focused: 'none' });
        }
        case ActionTypes.FocusInputLocation: {
            const nextState = Object.assign(Object.assign({}, state), { focused: 'location' });
            if (((_a = state.selectedLocation) === null || _a === void 0 ? void 0 : _a.id) === ID_OPTION_CURRENT_LOCATION) {
                nextState.searchLocationKeywords = '';
            }
            return nextState;
        }
        case ActionTypes.FocusInputSearch:
            const nextState = Object.assign(Object.assign({}, state), { focused: 'search' });
            if (state.isMobile) {
                return resetSearchLocationKeywords(nextState);
            }
            return nextState;
        case ActionTypes.ChangeInputLocation:
            return Object.assign(Object.assign({}, state), { searchLocationKeywords: action.payload });
        case ActionTypes.ChangeInputSearch: {
            const keyword = action.payload;
            return Object.assign(Object.assign({}, state), { searchKeywords: keyword, isLoadingSearchResults: keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale] });
        }
        case ActionTypes.SelectCurrentLocation:
            return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
        case ActionTypes.ClearInputLocation:
            return Object.assign(Object.assign({}, state), { focused: 'location', cities: state.initialCities, searchLocationKeywords: '' });
        case ActionTypes.ClearInputSearch:
            return Object.assign(Object.assign({}, state), { focused: 'search', searchKeywords: '' });
        case ActionTypes.SelectLocation:
            return Object.assign(Object.assign({}, state), { focused: 'none', selectedLocation: action.payload, searchLocationKeywords: action.payload.name });
        case ActionTypes.SelectSearchResult:
            return Object.assign(Object.assign({}, state), { searchKeywords: action.payload.name, isMobileModalOpened: false, focused: 'none', navigateTo: action.payload.url });
        case ActionTypes.FetchCitiesStart:
            return Object.assign(Object.assign({}, state), { isLoadingCities: true });
        case ActionTypes.FetchCitiesFinish:
            return Object.assign(Object.assign({}, state), { isLoadingCities: false });
        case ActionTypes.FetchSearchResultsStart:
            return Object.assign(Object.assign({}, state), { isLoadingSearchResults: true });
        case ActionTypes.FetchSearchResultsFinish:
            return Object.assign(Object.assign({}, state), { isLoadingSearchResults: false });
        case ActionTypes.FetchSearchResultsComplete: {
            const nextState = Object.assign(Object.assign({}, state), { searchResults: action.payload });
            if (state.initialSearchResults.length === 0) {
                nextState.initialSearchResults = action.payload;
            }
            return nextState;
        }
        case ActionTypes.FetchCitiesByGeoIpComplete: {
            let { cities } = action.payload;
            const { default: defaultCity } = action.payload;
            cities = cities.filter((c) => c.id !== defaultCity.id);
            cities.unshift(defaultCity);
            if (state.initialSelectedCity &&
                !cities.find((c) => c.id === state.initialSelectedCity.id)) {
                cities.unshift(state.initialSelectedCity);
            }
            const nextState = Object.assign(Object.assign({}, state), { defaultCity, initialCities: cities, cities });
            if (state.geoLocationPermission === 'denied' &&
                !state.initialSelectedCity) {
                nextState.selectedLocation = defaultCity;
                nextState.searchLocationKeywords = defaultCity.name;
            }
            return nextState;
        }
        case ActionTypes.FetchCitiesByKeywordComplete:
            return Object.assign(Object.assign({}, state), { cities: action.payload });
        case ActionTypes.DisplayInitialCities:
            return Object.assign(Object.assign({}, state), { cities: state.initialCities });
        case ActionTypes.DisplayInitialSearchResults:
            return Object.assign(Object.assign({}, state), { searchResults: state.initialSearchResults, isLoadingSearchResults: false });
        case ActionTypes.GrantGeoLocationPermission:
            return Object.assign(Object.assign({}, state), { geoLocationPermission: 'granted', geoLocationCoordinates: action.payload });
        case ActionTypes.DenyGeoLocationPermission:
            return Object.assign(Object.assign({}, state), { geoLocationPermission: 'denied', geoLocationCoordinates: null });
        case ActionTypes.OpenMobileModal:
            return Object.assign(Object.assign({}, state), { isMobileModalOpened: true });
        case ActionTypes.CloseMobileModal:
            return Object.assign(Object.assign({}, state), { isMobileModalOpened: false });
        case ActionTypes.UpdateInitialSearchValue:
            return Object.assign(Object.assign({}, state), { searchKeywords: action.payload });
        case ActionTypes.SetInputSearchPlaceholder:
            return Object.assign(Object.assign({}, state), { inputSearchPlaceholder: action.payload });
        default:
            return state;
    }
}

const StyledSearchBarInputsWrapper = styled.div `
  display: flex;
  gap: 16px;
  ${MediaQueries.mbDown} {
    flex-direction: column;
    padding: 14px;
    background-color: ${theme.colors.primary50};

    input {
      filter: drop-shadow(0px 4px 8px rgba(0, 0, 0, 0.04))
        drop-shadow(0px 0px 2px rgba(0, 0, 0, 0.06))
        drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.04));
    }
  }

  input {
    background-color: white;
  }
`;
const StyledInputWrapper = styled.div `
  position: relative;
`;
const StyledInputLocationWrapper = styled(StyledInputWrapper) `
  flex: 1;
`;
const StyledInputSearchWrapper = styled(StyledInputWrapper) `
  flex: 2;
`;
const StyledClearIcon = styled(ClearIcon) `
  display: none;
  &.shown {
    display: block;
  }
`;

const SearchIcon = () => (React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18" },
    React__default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M2.97887 8.15493C2.97887 5.29627 5.29627 2.97887 8.15493 2.97887C11.0136 2.97887 13.331 5.29627 13.331 8.15493C13.331 11.0136 11.0136 13.331 8.15493 13.331C5.29627 13.331 2.97887 11.0136 2.97887 8.15493ZM8.15493 1.5C4.47951 1.5 1.5 4.47951 1.5 8.15493C1.5 11.8303 4.47951 14.8099 8.15493 14.8099C9.72624 14.8099 11.1704 14.2653 12.3089 13.3546L15.2377 16.2834C15.5265 16.5722 15.9947 16.5722 16.2834 16.2834C16.5722 15.9947 16.5722 15.5265 16.2834 15.2377L13.3546 12.3089C14.2653 11.1704 14.8099 9.72624 14.8099 8.15493C14.8099 4.47951 11.8303 1.5 8.15493 1.5Z", fill: "white" })));
const StyledSearchIcon = styled.button `
  min-height: 100%;
  border-radius: 6px;
  background-color: ${theme.colors.primaryBase};
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 11px;
  cursor: pointer;
  flex: 0.3;

  ${MediaQueries.mbDown} {
    --margin: 16px;
    min-height: 44px;
    margin: var(--margin);
    width: calc(100% - var(--margin) * 2);
    position: absolute;
    bottom: 0;
  }

  &:hover {
    background-color: ${theme.colors.primaryHover};
  }

  &:active {
    background-color: ${theme.colors.primaryActive};
  }

  &:focus-visible {
    outline: 1px solid black;
  }
`;
const StyledText$1 = styled(Text) `
  font-weight: ${theme.sizes.fwSemiBold};
`;
const SearchButton = ({ onClick }) => {
    const { t } = useTranslations();
    const title = t('booking.searchBar.searchButton');
    return (React__default.createElement(StyledSearchIcon, { onClick: onClick, title: title },
        React__default.createElement(SearchIcon, null),
        React__default.createElement(StyledText$1, { size: "s3", color: "white" }, title)));
};

function SearchInputs({ isMobile, state, dispatch, debouncedFetchCitiesByKeyword, debouncedFetchSearchResults, focusLocationInput, focusSearchInput, renderLocationResults, renderSearchResults, locationTrackingAttributes, trackingAttributes, onSearch, initalSearchValue, }) {
    const inputLocationWrapperRef = useRef(null);
    const inputSearchWrapperRef = useRef(null);
    const { focused, searchLocationKeywords, geoLocationPermission, selectedLocation, searchKeywords, inputSearchPlaceholder, } = state;
    const { t } = useTranslations();
    useAnimatedPlaceholder({
        wrapperRef: inputSearchWrapperRef,
        disabled: !!inputSearchPlaceholder,
    });
    useOutsideClick(inputLocationWrapperRef, () => {
        if (!isMobile) {
            dispatch({ type: ActionTypes.ClickOutsideInputLocation });
        }
    });
    useOutsideClick(inputSearchWrapperRef, () => {
        if (!isMobile) {
            dispatch({ type: ActionTypes.ClickOutsideInputSearch });
        }
    });
    function handleLocationInputClear() {
        dispatch({ type: ActionTypes.ClearInputLocation });
        debouncedFetchCitiesByKeyword.cancel();
        focusLocationInput();
    }
    function handleSearchInputClear() {
        dispatch({ type: ActionTypes.ClearInputSearch });
        debouncedFetchSearchResults.cancel();
        debouncedFetchSearchResults('', state);
        focusSearchInput();
    }
    const searchInputPinIconColor = useMemo(() => {
        if (geoLocationPermission === 'granted' &&
            (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === ID_OPTION_CURRENT_LOCATION) {
            return theme.colors.primaryBase;
        }
        else {
            return theme.colors.gray400;
        }
    }, [geoLocationPermission, selectedLocation]);
    const handleSearchInputChange = useCallback(function handleSearchInputChange(value) {
        dispatch({ type: ActionTypes.ChangeInputSearch, payload: value });
        if (typeof onSearch === 'function') {
            return;
        }
        if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale] ||
            initalSearchValue) {
            debouncedFetchSearchResults(value.trim(), state);
        }
        else {
            debouncedFetchSearchResults.cancel();
            dispatch({ type: ActionTypes.DisplayInitialSearchResults });
        }
    }, [dispatch, state]);
    const handleSearchLocationInputChange = useCallback(function handleSearchLocationInputChange(value) {
        dispatch({ type: ActionTypes.ChangeInputLocation, payload: value });
        if (value.trim().length > SEARCH_KEYWORD_MIN_LENGTH[state.locale]) {
            debouncedFetchCitiesByKeyword(value.trim());
        }
        else {
            debouncedFetchCitiesByKeyword.cancel();
            dispatch({ type: ActionTypes.DisplayInitialCities });
        }
    }, [debouncedFetchCitiesByKeyword, dispatch]);
    const handleKeyPress = (e) => {
        if (state.autoCompleteDisabled && e.key === 'Enter' && onSearch) {
            onSearch({
                cityId: state.selectedLocation.id,
                keyword: searchKeywords,
            });
        }
    };
    return (React__default.createElement(StyledSearchBarInputsWrapper, null,
        React__default.createElement(StyledInputLocationWrapper, { ref: inputLocationWrapperRef },
            React__default.createElement(StyledInput, { inputClassName: focused === 'location' ? 'focused' : undefined, placeholder: t('booking.searchBar.locationPlaceholder'), autoComplete: "off", name: "search-location", displayIcon: React__default.createElement(PinIcon, { className: "location-pin-icon", color: searchInputPinIconColor }), actionIcon: React__default.createElement(StyledClearIcon, { color: theme.colors.gray300, className: searchLocationKeywords !== '' ? 'shown' : '' }), onActionClick: handleLocationInputClear, value: searchLocationKeywords, onChange: handleSearchLocationInputChange, onFocus: () => dispatch({ type: ActionTypes.FocusInputLocation }), size: "md", trackingAttributes: locationTrackingAttributes }),
            !isMobile && renderLocationResults()),
        React__default.createElement(StyledInputSearchWrapper, { ref: inputSearchWrapperRef },
            React__default.createElement(StyledInput, { placeholder: inputSearchPlaceholder ||
                    t('booking.searchBar.searchInput.placeholder'), autoComplete: "off", name: "search-results", actionIcon: React__default.createElement(StyledClearIcon, { color: theme.colors.gray300, className: searchKeywords !== '' ? 'shown' : '' }), onActionClick: handleSearchInputClear, value: searchKeywords, onChange: handleSearchInputChange, onFocus: () => dispatch({ type: ActionTypes.FocusInputSearch }), inputClassName: focused === 'search' ? 'focused' : undefined, size: "md", trackingAttributes: trackingAttributes, onKeyPress: handleKeyPress, enterKeyHint: state.autoCompleteDisabled ? 'search' : undefined }),
            !isMobile && renderSearchResults()),
        state.autoCompleteDisabled && !state.isMobile && (React__default.createElement(SearchButton, { onClick: () => {
                onSearch({
                    cityId: state.selectedLocation.id,
                    keyword: searchKeywords,
                });
            } }))));
}

const DoctorIcon = () => (React__default.createElement("svg", { width: "14", height: "18", viewBox: "0 0 14 18" },
    React__default.createElement("path", { d: "M7 .667c-1.702 0-3.36.146-4.48.365a1.67 1.67 0 0 0-1.353 1.64v2.162c0 .459.374.833.833.833h10a.835.835 0 0 0 .833-.833V2.698c0-.804-.566-1.487-1.354-1.64C10.356.84 8.693.667 7 .667m-.833.833h1.666v.834h.834V4h-.834v.834H6.167V4h-.834V2.334h.834zm-4.74 5a8 8 0 0 0-.234 1.276c-.046.404-.137 1.478-.13 1.589a1.94 1.94 0 0 0-.73 1.536c0 .935.645 1.735 1.51 1.928.902 2.19 2.71 4.505 5.157 4.505s4.255-2.338 5.156-4.532a1.935 1.935 0 0 0 1.51-1.9 1.94 1.94 0 0 0-.729-1.537c.007-.11-.08-1.205-.13-1.615a8.4 8.4 0 0 0-.234-1.25H5.359c1.169 1.706 3.916.687 5.678 1.12.537 1.172.13 2.813.13 2.813l.65.208c.095.03.183.114.183.26 0 .157-.114.293-.312.287l-.678-.104-.234.65C9.966 14.05 8.413 15.668 7 15.668s-2.965-1.618-3.776-3.932l-.26-.651-.704.104c-.143 0-.26-.13-.26-.287a.26.26 0 0 1 .182-.26l.651-.208c-.1.12-.423-1.729 0-2.396.759-.524 1.394-.16 2.292-1.537zm3.75 2.552c-.605 0-1.094.502-1.094 1.12s.489 1.12 1.094 1.12 1.094-.501 1.094-1.12c0-.618-.488-1.12-1.094-1.12m3.646 0c-.606 0-1.094.502-1.094 1.12s.488 1.12 1.094 1.12c.605 0 1.094-.501 1.094-1.12 0-.618-.489-1.12-1.094-1.12", fill: "#9AA2AC" })));
const ServiceIcon = () => (React__default.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18" },
    React__default.createElement("path", { d: "M9 .667A8.33 8.33 0 0 0 2.333 4H4.6A6.7 6.7 0 0 1 9 2.334c1.637 0 3.2.612 4.401 1.666h2.266A8.33 8.33 0 0 0 9 .667M1.786 4.834c-.71 2.207-1.12 4.765-1.12 7.5 0 1.751.16 3.434.47 5h15.729c.309-1.566.468-3.249.468-5 0-2.735-.41-5.293-1.12-7.5zM9 7.334a4.166 4.166 0 1 1 0 8.332 4.166 4.166 0 0 1 0-8.332M8.167 9v1.667H6.5v1.667h1.667V14h1.666v-1.666H11.5v-1.667H9.833V9z", fill: "#9AA2AC" })));
const HospitalIcon = () => (React__default.createElement("svg", { width: "16", height: "17", viewBox: "0 0 16 17" },
    React__default.createElement("path", { d: "M8 .667.5 5.635v9.199c0 .92.746 1.666 1.667 1.666h11.666c.921 0 1.667-.745 1.667-1.666V5.635zm3.333 10h-2.5v2.5H7.167v-2.5h-2.5V9h2.5V6.5h1.666V9h2.5z", fill: "#9AA2AC" })));
const SpecialtyIcon = () => (React__default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" },
    React__default.createElement("path", { d: "M3.833.5a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667M10.5.5c-.92 0-1.667.746-1.667 1.667V5.5c0 .92.746 1.667 1.667 1.667h3.333c.921 0 1.667-.746 1.667-1.667V2.167C15.5 1.246 14.754.5 13.833.5zM3.833 8.833a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667m8.334 0a3.333 3.333 0 1 0 0 6.667 3.333 3.333 0 0 0 0-6.667", fill: "#9AA2AC" })));

const StyledTypeHeader = styled.header `
  display: flex;
  justify-content: space-between;
  padding: 12px 24px;
  background-color: ${theme.colors.neutral50};
  box-shadow: inset 0px 1px 0px #e4e8ec;
`;
const StyledInfoWrapper = styled.div `
  display: grid;
  flex: 2;
  align-items: center;
  gap: 16px;
  grid-template-columns: 16px 1fr;
`;
const StyledTypeName = styled.p `
  color: ${theme.colors.neutral800};
  font-size: 14px;
  font-weight: ${theme.sizes.fwSemiBold};
  letter-spacing: -0.2px;
  line-height: 22px;
`;
const StyledSeeMoreButton = styled.button `
  flex: 1;
  cursor: pointer;
  text-align: end;
`;
const StyledResultsContainer = styled.section `
  padding: 12px 16px;
  --rowGap: 16px;
  --graphicSize: 32px;

  ${MediaQueries.tdUp} {
    --rowGap: 8px;
  }
`;
const StyledItemsWrapper = styled.ul `
  --gap: 16px;
  ${MediaQueries.tdUp} {
    --gap: 8px;
  }

  display: grid;
  overflow: hidden;
  gap: var(--gap);
  transition: max-height 0.8s ease-out;

  ${({ isMore }) => isMore &&
    `
     height: auto;
     max-height: 0;
     margin-top: var(--gap);
   `}

  ${({ isShown }) => isShown &&
    `
     max-height: 600px;
    `}

@media (prefers-reduced-motion) {
    transition: none;
  }

  ${MediaQueries.tdUp} {
    grid-template-columns: 1fr 1fr;
  }
`;
const StyledSeeMore = styled(Text) `
  margin-top: 12px;
  margin-bottom: 8px;
  cursor: pointer;
  text-align: start;
  text-transform: capitalize;
`;

const StyledResult = styled.li `
  display: flex;
  align-items: center;
  gap: var(--rowGap);
  cursor: pointer;
  &.not-nav {
    cursor: default;
  }
`;
const StyledRoundedIconWrapper = styled.div `
  --wrapper-size: var(--graphicSize);
  border-radius: calc(var(--wrapper-size) / 2);
  background-color: var(--neutral50);
  width: var(--wrapper-size);
  height: var(--wrapper-size);
  aspect-ratio: 1/1;
  overflow: hidden;

  ${({ type }) => type &&
    type === 'doctors' &&
    `
    border-radius: calc(var(--graphicSize) / 2);
    `}

  img {
    width: var(--graphicSize);
    height: var(--graphicSize);
    ${({ type }) => type && type === 'doctors'
    ? `

        object-fit: cover;  
      `
    : `
        object-fit: contain;
      `}
  }

  &:focus-visible {
    outline: 1px solid ${theme.colors.gray600};
  }
`;
const StyledText = styled(Text) `
  line-height: 22px;
  letter-spacing: -0.2px;

  ${MediaQueries.tdUp} {
    &[data-size='p3'] {
      font-size: 14px;
    }
  }
`;
const StyledPictureWrapper = styled.figure `
  max-width: var(--graphicSize);
  min-width: var(--graphicSize);
`;
const StyledLocationPin = styled.svg `
  margin: 0 auto;
  display: block;
`;
const StyledImageSkeletonWrapper = styled.div `
  display: grid;
  place-items: center;
`;

const defaultThumbnailByType = {
    doctors: DefaultThumbnailDoctor,
    services: DefaultThumbnailService,
};
const ResultSectionItem = ({ type, item, imageUrl, className, onClickItem, }) => {
    const onKeyDown = (e) => {
        if (e.key === 'Enter' || e.key === 'Space') {
            if (onClickItem) {
                onClickItem(item);
            }
        }
    };
    const defaultThumbnail = useMemo(() => {
        const Cmp = defaultThumbnailByType[type] || DefaultThumbnailAny;
        return React__default.createElement(Cmp, { width: 32, height: type === 'services' ? 32 : 24 });
    }, [type]);
    return (React__default.createElement(StyledResult, { onClick: () => onClickItem && onClickItem(item), onKeyDown: onKeyDown, tabIndex: 0, role: "button", className: className },
        React__default.createElement(StyledPictureWrapper, null, type === 'hospitals' ? (React__default.createElement(StyledLocationPin, { width: "12", height: "16", viewBox: "0 0 12 16" },
            React__default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M0.75 5.94873C0.75 3.04623 3.0975 0.69873 6 0.69873C8.9025 0.69873 11.25 3.04623 11.25 5.94873C11.25 9.07623 7.935 13.3887 6.5775 15.0312C6.2775 15.3912 5.73 15.3912 5.43 15.0312C4.065 13.3887 0.75 9.07623 0.75 5.94873ZM4.125 5.94873C4.125 6.98373 4.965 7.82373 6 7.82373C7.035 7.82373 7.875 6.98373 7.875 5.94873C7.875 4.91373 7.035 4.07373 6 4.07373C4.965 4.07373 4.125 4.91373 4.125 5.94873Z", fill: "#9AA2AC" }))) : (React__default.createElement(StyledRoundedIconWrapper, { type: type }, imageUrl ? (React__default.createElement("img", { src: imageUrl, width: 32, height: type === 'services' ? 32 : 24, loading: "lazy" })) : (defaultThumbnail)))),
        React__default.createElement(StyledText, { color: theme.colors.gray800, size: "p3" }, item.name)));
};

const ResultSection = ({ type, data, state, dispatch, itemsToShow, itemsToShowDesktop, isMobile, isLoading, keyword, isNavResultItem, }) => {
    const [seeMoreOpen, setSeeMoreOpen] = useState(false);
    const { t, locale } = useTranslations();
    const { selectedLocation, searchKeywords } = state;
    const slugs = useMemo(() => LOCALIZED_SLUGS[locale], [locale]);
    const isMalay = locale === 'ms-MY';
    const typeInformation = useMemo(() => {
        return {
            doctors: {
                name: t('booking.searchPopup.doctors'),
                icon: React__default.createElement(DoctorIcon, null),
                slug: slugs.DOCTOR,
            },
            services: {
                name: t('booking.searchPopup.services'),
                icon: React__default.createElement(ServiceIcon, null),
                slug: slugs.SERVICE,
            },
            hospitals: {
                name: t('booking.searchPopup.hospitals'),
                icon: React__default.createElement(HospitalIcon, null),
                slug: slugs.HOSPITAL,
            },
            specialties: {
                name: t('booking.searchPopup.specialties'),
                icon: React__default.createElement(SpecialtyIcon, null),
                slug: slugs.SPECIALTIES,
            },
        };
    }, [type, slugs]);
    const typeSlug = useMemo(() => typeInformation[type].slug, [typeInformation]);
    const showItemCount = isMobile ? itemsToShow : itemsToShowDesktop;
    function onClickItem(item) {
        let url = '';
        switch (type) {
            case 'specialties':
                url = `/${selectedLocation.slug}/${typeInformation.doctors.slug}/${item.slug}`;
                break;
            case 'services':
                url = `/${selectedLocation.slug}/${typeSlug}/${item.slug}`;
                break;
            case 'doctors':
            case 'hospitals':
                url = `/${typeSlug}/${item.slug}-${item.id}`;
                break;
        }
        if (url) {
            dispatch({
                type: ActionTypes.SelectSearchResult,
                payload: { name: item.name, url },
            });
        }
    }
    function renderItem(item) {
        return (React__default.createElement(ResultSectionItem, { key: item.id, item: item, type: type, imageUrl: item.logo || item.avatar || item.thumbnail, className: !isNavResultItem ? 'not-nav' : '', onClickItem: isNavResultItem && onClickItem }));
    }
    function onSeeAllClick() {
        let url = '';
        switch (type) {
            case 'specialties':
                url = `/${typeSlug}`;
                break;
            case 'services':
            case 'doctors':
            case 'hospitals':
                url = `/${selectedLocation.slug}/${typeSlug}`;
                break;
        }
        if (url) {
            dispatch({ type: ActionTypes.NavigateTo, payload: url });
        }
    }
    function onClickSearchByKeyword() {
        const { slug: typeSlug } = typeInformation[type];
        const url = `/${selectedLocation.slug}/${typeSlug}?q=${searchKeywords}`;
        dispatch({ type: ActionTypes.NavigateTo, payload: url });
    }
    return (React__default.createElement("section", null,
        React__default.createElement(StyledTypeHeader, null,
            React__default.createElement(StyledInfoWrapper, null,
                typeInformation[type].icon,
                React__default.createElement(StyledTypeName, null, typeInformation[type].name)),
            (keyword.trim().length <= SEARCH_KEYWORD_MIN_LENGTH[locale] ||
                isMalay) && (React__default.createElement(StyledSeeMoreButton, { onClick: onSeeAllClick },
                React__default.createElement(Text, { size: "p3", color: theme.colors.primaryBase }, t('booking.searchPopup.seeAll'))))),
        (isLoading || (data && data.length > 0)) && (React__default.createElement(StyledResultsContainer, null,
            React__default.createElement(StyledItemsWrapper, null,
                isLoading &&
                    Array(2)
                        .fill(undefined)
                        .map((_, i) => (React__default.createElement(StyledResult, { key: type + 'loading' + i },
                        React__default.createElement(StyledPictureWrapper, null,
                            React__default.createElement(StyledImageSkeletonWrapper, null,
                                React__default.createElement(Skeleton, { height: 14, width: type === 'hospitals' ? 12 : 32, style: {
                                        maxWidth: 'var(--graphicSize)',
                                        minHeight: 'var(--graphicSize)',
                                    } }))),
                        React__default.createElement(Skeleton, { width: 120, height: 24 })))),
                !isLoading &&
                    data &&
                    data.length > 0 &&
                    data.slice(0, showItemCount).map(renderItem)),
            React__default.createElement(StyledItemsWrapper, { isShown: seeMoreOpen, isMore: true }, data.slice(showItemCount, -1).map(renderItem)),
            type === 'specialties' &&
                showItemCount < data.length &&
                !isLoading && (React__default.createElement("button", { onClick: () => setSeeMoreOpen(!seeMoreOpen) },
                React__default.createElement(StyledSeeMore, { size: "p3", color: theme.colors.primaryBase }, seeMoreOpen
                    ? t('booking.searchPopup.seeLessSpecialties')
                    : t('booking.searchPopup.seeMoreSpecialties')))),
            type !== 'specialties' &&
                (showItemCount < data.length || isMalay) &&
                !isLoading &&
                keyword.trim().length > SEARCH_KEYWORD_MIN_LENGTH[locale] && (React__default.createElement("button", { onClick: onClickSearchByKeyword },
                React__default.createElement(StyledSeeMore, { size: "p3", color: theme.colors.primaryBase }, t(`booking.searchPopup.searchIn.${type}`, {
                    name: keyword,
                })))))),
        !isLoading && (data === null || data === void 0 ? void 0 : data.length) === 0 && (React__default.createElement(StyledResultsContainer, null,
            React__default.createElement(Text, { size: "sm", color: theme.colors.gray400 }, t('booking.searchBar.noResults'))))));
};

const StyledSection = styled.section `
  background-color: white;
  border-radius: 4px;
  position: absolute;
  width: 100%;
  z-index: 30;

  ${MediaQueries.tdUp} {
    box-shadow: 0px 24px 32px rgba(0, 0, 0, 0.04),
      0px 16px 24px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04),
      0px 0px 1px rgba(0, 0, 0, 0.04);
  }
`;
const SearchResults = ({ data, state, dispatch, isMobile, isLoading, keyword, hideResults, isNavResultItem, }) => {
    return (React__default.createElement(StyledSection, null, data &&
        data.map((data) => {
            if (hideResults && hideResults.includes(data.type)) {
                return React__default.createElement(React__default.Fragment, null);
            }
            return (React__default.createElement(ResultSection, { type: data.type, state: state, dispatch: dispatch, itemsToShow: 2, itemsToShowDesktop: 4, key: data.type, data: data.results, isMobile: isMobile, isLoading: isLoading, keyword: keyword, isNavResultItem: isNavResultItem }));
        })));
};

function useSearchBarApi({ dispatch, careApiDomain, locale = 'vi-VN', }) {
    const fetchCitiesApi = useCallback(function fetchCitiesApi(path, params = {}) {
        const url = `${careApiDomain}${path}`;
        dispatch({ type: ActionTypes.FetchCitiesStart });
        return fetch(getApiPath(url, params, locale), { method: 'GET' })
            .then((res) => res.json())
            .then((data) => {
            if (data._status !== 1 || !data._data) {
                console.log('error loading cities', data);
                return Promise.reject(data);
            }
            return data === null || data === void 0 ? void 0 : data._data;
        })
            .finally(() => dispatch({ type: ActionTypes.FetchCitiesFinish }));
    }, [locale]);
    const fetchCitiesByLocation = useCallback(function fetchCitiesByLocation({ coordinates }) {
        let params = {};
        const moreParams = {};
        if (coordinates) {
            params = {
                lat: coordinates.lat,
                lng: coordinates.lng,
            };
        }
        if (locale === 'ms-MY') {
            moreParams.noPaging = 1;
        }
        const requests = [
            fetchCitiesApi(PATHS.GET_CITY_BY_IP, Object.assign(Object.assign({}, params), moreParams)),
        ];
        if (locale === 'zh-TW') {
            requests.push(fetchCitiesApi(PATHS.GET_CITIES_LIST, { noPaging: 1 }));
        }
        return Promise.all(requests)
            .then(([data1, data2]) => {
            const data = Object.assign({}, data1);
            if (data2) {
                const citiesIds = data.cities.map((c) => c.id);
                data.cities = data.cities.concat(data2.cities.filter((c) => !citiesIds.includes(c.id)));
            }
            dispatch({
                type: ActionTypes.FetchCitiesByGeoIpComplete,
                payload: data,
            });
        })
            .catch((err) => console.error('error loading cities by location', err));
    }, [locale, careApiDomain, dispatch]);
    const fetchCitiesByKeyword = useCallback(function fetchCitiesByKeyword(keyword) {
        return fetchCitiesApi(PATHS.GET_CITIES_LIST, { keyword })
            .then((data) => {
            dispatch({
                type: ActionTypes.FetchCitiesByKeywordComplete,
                payload: data.cities,
            });
        })
            .catch((err) => console.error('error loading cities by keyword', err));
    }, [locale, careApiDomain, dispatch]);
    const fetchSearchResults = useCallback(function fetchSearchResults(searchKeywords, state) {
        const url = `${careApiDomain}${PATHS.GET_SEARCH_V2}`;
        dispatch({ type: ActionTypes.FetchSearchResultsStart });
        const { defaultCity, selectedLocation, geoLocationCoordinates } = state;
        let cityId = '';
        if (!selectedLocation || !defaultCity) {
            dispatch({ type: ActionTypes.FetchSearchResultsFinish });
            return;
        }
        const isCurrentLocationSelected = selectedLocation.id === ID_OPTION_CURRENT_LOCATION;
        if (isCurrentLocationSelected) {
            if (!geoLocationCoordinates) {
                cityId = defaultCity.id;
            }
        }
        else if (selectedLocation.id === ID_OPTION_ALL_LOCATION) {
            cityId = '';
        }
        else {
            cityId = selectedLocation.id;
        }
        const lat = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lat) || '';
        const lng = (geoLocationCoordinates === null || geoLocationCoordinates === void 0 ? void 0 : geoLocationCoordinates.lng) || '';
        return fetch(getApiPath(url, {
            domain: careApiDomain,
            searchType: 'global',
            keyword: searchKeywords.trim().length > SEARCH_KEYWORD_MIN_LENGTH[locale]
                ? searchKeywords.trim()
                : '',
            city: cityId === ID_OPTION_CURRENT_LOCATION ? '' : cityId,
            lat,
            lng,
        }, locale), {
            method: 'GET',
            headers: {
                accept: 'version=2.0.0.0',
            },
        })
            .then((res) => res.json())
            .then((data) => {
            if (data._status !== 1 || !data._data) {
                return Promise.reject(data);
            }
            return data === null || data === void 0 ? void 0 : data._data;
        })
            .then((results) => dispatch({
            type: ActionTypes.FetchSearchResultsComplete,
            payload: results,
        }))
            .catch((error) => {
            console.log('error loading search results', { url, error });
        })
            .finally(() => dispatch({ type: ActionTypes.FetchSearchResultsFinish }));
    }, [locale, careApiDomain, dispatch]);
    return {
        fetchCitiesByLocation,
        fetchCitiesByKeyword,
        fetchSearchResults,
    };
}

const BookingSearchBar = ({ isMobile, careApiDomain, geoLocationPermission: geoLocationPermissionFromProps, geoLocationCoordinates: geoLocationCoordinatesFromProps, initialSelectedCity: initialSelectedCityFromProps, initialSearchValue = '', careFrontDomain = '/care', isDebug = false, askForGeolocationPermission = false, gaTrackingSearchBar, gaTrackingLocationSearch, autoCompleteDisabled = false, inputSearchPlaceholder = '', isOptionAllLocation = false, hideResults = [], isNavResultItem = true, routerPush, onGeoLocationPermissionChange, onSearch, onChangeLocation, }) => {
    const { t, locale } = useTranslations();
    const wrapperRef = useRef(null);
    const hiddenInputRef = useRef(null);
    const [viewportHeight, setViewportHeight] = useState(undefined);
    const [isNavResultPage, setIsNavResultPage] = useState(false);
    const { geoLocationPermission: geoLocationPermissionFromHook, geoLocationCoordinates: geoLocationCoordinatesFromHook, requestGeoLocation, } = useGeolocation();
    const [state, dispatch] = useReducer(reducer, initialState, (s) => (Object.assign(Object.assign({}, s), { isDebug,
        isMobile, geoLocationPermission: geoLocationPermissionFromProps ||
            geoLocationPermissionFromHook ||
            'unset', geoLocationCoordinates: geoLocationCoordinatesFromProps ||
            geoLocationCoordinatesFromHook ||
            null, searchKeywords: initialSearchValue, initialSelectedCity: initialSelectedCityFromProps || null, selectedLocation: initialSelectedCityFromProps || s.selectedLocation || null, searchLocationKeywords: (initialSelectedCityFromProps === null || initialSelectedCityFromProps === void 0 ? void 0 : initialSelectedCityFromProps.name) || s.searchLocationKeywords, autoCompleteDisabled,
        inputSearchPlaceholder,
        locale })));
    const { navigateTo, focused, isLoadingCities, cities, searchKeywords, geoLocationPermission, selectedLocation, initialSelectedCity, defaultCity, searchResults, isLoadingSearchResults, isMobileModalOpened, inputSearchPlaceholder: inputSearchPlaceholderState, } = state;
    const { fetchCitiesByLocation, fetchCitiesByKeyword, fetchSearchResults } = useSearchBarApi({
        dispatch,
        locale,
        careApiDomain,
    });
    const currentLocationCityItem = useMemo(() => {
        var _a;
        return ({
            id: ID_OPTION_CURRENT_LOCATION,
            name: t('booking.searchBar.currentLocation'),
            slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.CURRENT,
        });
    }, [t, locale]);
    const debouncedFetchCitiesByKeyword = useMemo(() => debounce(fetchCitiesByKeyword, 400), [fetchCitiesByKeyword]);
    const debouncedFetchSearchResults = useMemo(() => debounce(fetchSearchResults, 400), [fetchSearchResults]);
    useEffect(() => {
        if (initialSearchValue !== '' &&
            initialSearchValue !== state.searchKeywords) {
            dispatch({
                type: ActionTypes.UpdateInitialSearchValue,
                payload: initialSearchValue,
            });
        }
    }, [initialSearchValue]);
    useEffect(() => {
        if (askForGeolocationPermission &&
            (selectedLocation === null || selectedLocation === void 0 ? void 0 : selectedLocation.id) === ID_OPTION_CURRENT_LOCATION &&
            geoLocationPermission === 'unset') {
            requestGeoLocation();
        }
    }, [askForGeolocationPermission, selectedLocation, geoLocationPermission]);
    useEffect(() => {
        if (!geoLocationPermissionFromProps &&
            geoLocationPermission !== geoLocationPermissionFromHook) {
            if (geoLocationPermissionFromHook === 'granted' &&
                geoLocationCoordinatesFromHook) {
                dispatch({
                    type: ActionTypes.GrantGeoLocationPermission,
                    payload: geoLocationCoordinatesFromHook,
                });
            }
            else if (geoLocationPermissionFromHook === 'denied') {
                dispatch({ type: ActionTypes.DenyGeoLocationPermission });
            }
        }
    }, [
        geoLocationPermission,
        geoLocationPermissionFromHook,
        geoLocationCoordinatesFromHook,
        geoLocationPermissionFromProps,
    ]);
    useEffect(() => {
        if (navigateTo) {
            if (routerPush) {
                routerPush(navigateTo);
            }
            else {
                window.location.href = `${careFrontDomain}${navigateTo}`;
            }
        }
    }, [navigateTo]);
    const selectCurrentLocation = useCallback(function selectCurrentLocation() {
        dispatch({
            type: ActionTypes.SelectCurrentLocation,
            payload: currentLocationCityItem,
        });
    }, [t, dispatch]);
    useEffect(() => {
        var _a;
        if (geoLocationPermission !== 'denied' && !initialSelectedCity) {
            dispatch({
                type: ActionTypes.SelectLocation,
                payload: {
                    name: t('booking.searchBar.allLocations'),
                    id: ID_OPTION_ALL_LOCATION,
                    slug: (_a = LOCALIZED_SLUGS[locale]) === null || _a === void 0 ? void 0 : _a.ALL,
                },
            });
        }
        if (onGeoLocationPermissionChange) {
            onGeoLocationPermissionChange(geoLocationPermission, state.geoLocationCoordinates);
        }
        if (isMobile && geoLocationPermission === 'granted' && selectedLocation) {
            dispatch({ type: ActionTypes.FocusInputSearch });
        }
        fetchCitiesByLocation({ coordinates: state.geoLocationCoordinates });
    }, [geoLocationPermission]);
    useEffect(() => {
        if (selectedLocation && defaultCity) {
            fetchSearchResults(state.searchKeywords, state);
        }
    }, [selectedLocation, defaultCity]);
    useEffect(() => {
        if (inputSearchPlaceholder !== inputSearchPlaceholderState) {
            dispatch({
                type: ActionTypes.SetInputSearchPlaceholder,
                payload: inputSearchPlaceholder,
            });
        }
    }, [inputSearchPlaceholder, inputSearchPlaceholderState]);
    useEffect(() => {
        if (isMobileModalOpened) {
            document.body.classList.add('care-popup-open');
        }
        else {
            document.body.classList.remove('care-popup-open');
        }
    }, [isMobileModalOpened]);
    const handleLocationClick = useCallback(function handleLocationClick(city) {
        if (locale === 'ms-MY') {
            setIsNavResultPage(true);
        }
        dispatch({ type: ActionTypes.SelectLocation, payload: city });
        if (locale !== 'ms-MY') {
            focusSearchInput();
        }
        if (onChangeLocation) {
            onChangeLocation(city);
        }
    }, [t, dispatch]);
    function handleCurrentLocationClick() {
        if (locale === 'ms-MY') {
            setIsNavResultPage(true);
        }
        if (isMobile && state.geoLocationPermission !== 'granted') {
            requestGeoLocation();
        }
        else {
            selectCurrentLocation();
            if (locale !== 'ms-MY') {
                focusSearchInput();
            }
        }
    }
    function handleMobileFakeInputClick() {
        var _a;
        return __awaiter(this, void 0, void 0, function* () {
            if (hiddenInputRef.current) {
                hiddenInputRef.current.focus();
            }
            dispatch({ type: ActionTypes.OpenMobileModal });
            yield Promise.resolve();
            if (wrapperRef.current) {
                (_a = wrapperRef.current
                    .querySelector('input[name="search-location"]')) === null || _a === void 0 ? void 0 : _a.focus();
            }
        });
    }
    function focusLocationInput() {
        var _a;
        if (wrapperRef.current) {
            (_a = wrapperRef.current
                .querySelector('input[name="search-location"]')) === null || _a === void 0 ? void 0 : _a.focus();
        }
    }
    function focusSearchInput() {
        var _a;
        if (wrapperRef.current) {
            (_a = wrapperRef.current
                .querySelector('input[name="search-results"]')) === null || _a === void 0 ? void 0 : _a.focus();
        }
    }
    function handleMobileTopBarClose() {
        dispatch({ type: ActionTypes.CloseMobileModal });
    }
    function renderLocationResults() {
        if (focused !== 'location') {
            return null;
        }
        return (React__default.createElement(LocationResults, { isLoading: isLoadingCities, cities: cities, onLocationClick: handleLocationClick, onCurrentLocationClick: handleCurrentLocationClick, isLocationLoading: isLoadingCities, geoLocationPermission: geoLocationPermission, selectedLocation: selectedLocation, isOptionAllLocation: isOptionAllLocation }));
    }
    function renderSearchResults() {
        if (focused !== 'search') {
            return null;
        }
        if (state.autoCompleteDisabled) {
            if (!isMobile) {
                return null;
            }
            return (React__default.createElement(SearchButton, { onClick: () => {
                    onSearch({
                        cityId: state.selectedLocation.id,
                        keyword: searchKeywords,
                    });
                    handleMobileTopBarClose();
                } }));
        }
        return (React__default.createElement(SearchResults, { data: searchResults, state: state, dispatch: dispatch, isMobile: false, keyword: searchKeywords, isLoading: isLoadingSearchResults, hideResults: hideResults, isNavResultItem: isNavResultItem }));
    }
    function renderSearchInputs() {
        return (React__default.createElement(SearchInputs, { isMobile: isMobile, state: state, dispatch: dispatch, debouncedFetchCitiesByKeyword: debouncedFetchCitiesByKeyword, debouncedFetchSearchResults: debouncedFetchSearchResults, focusLocationInput: focusLocationInput, focusSearchInput: focusSearchInput, renderLocationResults: renderLocationResults, renderSearchResults: renderSearchResults, trackingAttributes: gaTrackingSearchBar, locationTrackingAttributes: gaTrackingLocationSearch, onSearch: onSearch, initalSearchValue: initialSearchValue }));
    }
    useEffect(() => {
        if (window.visualViewport) {
            const resizeHandler = (evt) => {
                const viewport = evt.target;
                setViewportHeight(viewport === null || viewport === void 0 ? void 0 : viewport.height);
            };
            window.visualViewport.addEventListener('resize', resizeHandler, {
                passive: true,
            });
            return () => {
                window.visualViewport.removeEventListener('resize', resizeHandler);
            };
        }
    }, [setViewportHeight]);
    useEffect(() => {
        // Apply for ms-MY. Navigation to result page after selected location
        if (selectedLocation && isNavResultPage && locale === 'ms-MY') {
            const url = `/${selectedLocation.slug}/hospital`;
            dispatch({ type: ActionTypes.NavigateTo, payload: url });
            setIsNavResultPage(false);
        }
    }, [isNavResultPage, locale, selectedLocation]);
    if (isMobile) {
        return (React__default.createElement(React__default.Fragment, null,
            React__default.createElement(Global, { styles: css `
            .care-popup-open {
              overflow: hidden;
              position: fixed;
              &::before {
                content: '';
                inset: 0;
                position: absolute;
                background-color: white;
                min-height: 100vh;
                min-width: 100vw;
                z-index: 2;
              }
            }
          ` }),
            React__default.createElement(StyledHiddenInputMobile, { ref: hiddenInputRef }),
            React__default.createElement(StyledSearchBarMobileWrapper, { id: "booking-search-bar", ref: wrapperRef, "data-is-modal": isMobile && isMobileModalOpened, style: {
                    '--mobile-care-searchbar-height': isMobileModalOpened && viewportHeight
                        ? `${viewportHeight}px`
                        : '100%',
                } }, !isMobileModalOpened ? (React__default.createElement(MobileFakeInput, { onClick: handleMobileFakeInputClick, focused: focused, value: searchKeywords, trackingAttributes: gaTrackingSearchBar, inputSearchPlaceholder: inputSearchPlaceholder })) : (React__default.createElement(React__default.Fragment, null,
                React__default.createElement(StyledSearchBarMobileModalHeader, null,
                    React__default.createElement(MobileTopBar, { headingText: t('booking.searchBar.searchButton'), onLeftClick: handleMobileTopBarClose }),
                    renderSearchInputs()),
                renderLocationResults(),
                renderSearchResults())))));
    }
    return (React__default.createElement(StyledSearchBarWrapper, { id: "booking-search-bar", ref: wrapperRef }, renderSearchInputs()));
};

export { BookingSearchBar };
