"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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Select = exports.InnerSelect = void 0;
require("./Select.global.scss");
const classnames_1 = __importDefault(require("classnames"));
const react_1 = __importStar(require("react"));
const Overlay_1 = require("../Overlay/Overlay");
const Text_1 = __importStar(require("../Text"));
const CombineState_1 = require("../../../hooks/CombineState");
const KeyboardControlOnSelect_1 = require("../../../hooks/KeyboardControlOnSelect");
const WindowSize_1 = require("../../../hooks/WindowSize");
const Color_1 = require("../../../util/Color");
const Icon_1 = __importStar(require("../Icon/Icon"));
const MOBILE_BREAKPOINT = 992;
const InnerSelect = ({ target, open, onClose, options = [], value, onChange, keyName, labelName, className, offset, renderOption, nativeOnMobile = false, overlay, renderLabel, hideExpandIcon, inputLabelColor, disableNative, renderNoOptions, }, ref) => {
    var _a, _b;
    const { width } = (0, WindowSize_1.useWindowSize)();
    const targetRef = (0, react_1.useRef)(null);
    const optionRefs = (0, react_1.useRef)({});
    const optionContainerRef = (0, react_1.useRef)(null);
    const [_open, _setIsOpen] = (0, CombineState_1.useCombinedState)(open, false);
    const flattenOptions = (0, react_1.useMemo)(() => {
        return options.reduce((result, optionGroupProbably) => {
            if (optionGroupProbably.options)
                return result.concat(optionGroupProbably.options);
            return result.concat(optionGroupProbably);
        }, []);
    }, [options]);
    // TODO: Force to fix later
    nativeOnMobile = false;
    const _onClose = (e) => {
        _setIsOpen(false);
        onClose === null || onClose === void 0 ? void 0 : onClose(e);
    };
    const overlayRef = (0, react_1.useRef)(null);
    (0, react_1.useImperativeHandle)(ref, () => overlayRef.current);
    const _onSelected = (value) => {
        onChange === null || onChange === void 0 ? void 0 : onChange(value);
        _setIsOpen(false);
    };
    const _getOption = (value) => {
        for (const option of options) {
            if (option.options && Array.isArray(option.options)) {
                for (const childOption of option.options) {
                    if (childOption[keyName] === value) {
                        return childOption;
                    }
                }
            }
            else {
                // If we're in here it means that this option doesn't have children and is in fact an individual group
                if (option[keyName] === value) {
                    return option;
                }
            }
        }
    };
    const { selectingItem, onItemMouseMove, onItemMouseLeave, onItemMouseEnter } = (0, KeyboardControlOnSelect_1.useKeyboardControlOnSelect)({
        onSelected: (item) => _onSelected(item[keyName]),
        isEnabled: !!_open,
        options,
        idName: keyName,
        overlayRef: overlayRef.current,
        defaultOption: _getOption(value),
        optionRefs,
        optionContainerRef,
    });
    const _getStringLabel = (value) => {
        const option = _getOption(value);
        return (option === null || option === void 0 ? void 0 : option[labelName]) || value || '';
    };
    const _getLabel = (value) => {
        const option = _getOption(value);
        if (renderLabel) {
            return renderLabel(option);
        }
        return _getStringLabel(value);
    };
    const _renderOptions = (options) => {
        if (!options)
            return null;
        return options.map((option, index) => {
            const isGroup = option.options;
            if (isGroup) {
                return _renderGroup(option.name, option.options);
            }
            return _renderOption({ option: option, key: index });
        });
    };
    const _renderGroup = (name, options) => {
        return (react_1.default.createElement(react_1.default.Fragment, null,
            react_1.default.createElement("div", { className: "rs-select--suggest-list-item --group-title" },
                react_1.default.createElement(Text_1.default, { type: Text_1.TextType.Small, color: Color_1.Color.DarkGrey }, name)),
            _renderOptions(options)));
    };
    const _renderOption = ({ option, key }) => {
        const isSelected = option[keyName] === value;
        const isSelecting = option[keyName] === (selectingItem === null || selectingItem === void 0 ? void 0 : selectingItem[keyName]);
        return (react_1.default.createElement("div", { ref: (ref) => (optionRefs.current[option[keyName]] = ref), key: key, className: (0, classnames_1.default)('rs-select--suggest-list-item', { '--selected': isSelected || isSelecting }), onClick: () => _onSelected(option[keyName]), onMouseEnter: () => {
                onItemMouseEnter(option);
            }, onMouseLeave: () => onItemMouseLeave(), onMouseMove: () => onItemMouseMove() },
            react_1.default.createElement(Text_1.default, { type: Text_1.TextType.Small, className: "rs-select--suggest-list-option-name" }, renderOption ? renderOption(option) : labelName ? option[labelName] : ''),
            isSelected && (react_1.default.createElement("span", { className: "rs-select--suggest-list-option-icon" },
                react_1.default.createElement(Icon_1.default, { icon: Icon_1.IconType.Check })))));
    };
    const native = width && width < MOBILE_BREAKPOINT && nativeOnMobile;
    const labelProps = {};
    if (inputLabelColor) {
        labelProps.style = { color: inputLabelColor };
    }
    return (react_1.default.createElement(react_1.default.Fragment, null,
        (native || !target || disableNative) && (react_1.default.createElement("span", Object.assign({ className: (0, classnames_1.default)('be-select', className), onClick: () => _setIsOpen(true), ref: targetRef }, labelProps),
            native ? (react_1.default.createElement("select", { value: value, onChange: (e) => onChange === null || onChange === void 0 ? void 0 : onChange(e.target.value) }, flattenOptions.map((item) => {
                return react_1.default.createElement("option", { value: value, key: item[keyName], label: _getStringLabel(item[keyName]) });
            }))) : (_getLabel(value)),
            hideExpandIcon ? null : react_1.default.createElement(Icon_1.default, { icon: Icon_1.IconType.Dropdown, color: Color_1.Color.DarkGrey }))),
        !native && (react_1.default.createElement(Overlay_1.Overlay, { offset: offset, usePortal: (_a = overlay === null || overlay === void 0 ? void 0 : overlay.usePortal) !== null && _a !== void 0 ? _a : true, followElement: target || targetRef.current || undefined, placement: (_b = overlay === null || overlay === void 0 ? void 0 : overlay.placement) !== null && _b !== void 0 ? _b : 'bottom-start', strategy: overlay === null || overlay === void 0 ? void 0 : overlay.strategy, open: open === undefined ? !!_open : open, onClose: _onClose, containerClassName: overlay === null || overlay === void 0 ? void 0 : overlay.containerClassName, overlayRef: overlayRef, hideStyles: overlay === null || overlay === void 0 ? void 0 : overlay.hideStyles },
            react_1.default.createElement("div", { ref: optionContainerRef, className: (0, classnames_1.default)('rs-select--suggest-list', overlay === null || overlay === void 0 ? void 0 : overlay.className) }, options.length ? _renderOptions(options) : react_1.default.createElement("div", { className: "rs-select--suggest-list-item" }, renderNoOptions === null || renderNoOptions === void 0 ? void 0 : renderNoOptions(targetRef)))))));
};
exports.InnerSelect = InnerSelect;
exports.Select = (0, react_1.forwardRef)(exports.InnerSelect);
//# sourceMappingURL=Select.js.map