"use strict";
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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 (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __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 __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntlPhoneInput = void 0;
// @ts-nocheck
var react_1 = __importDefault(require("react"));
var bem_react_classname_1 = require("bem-react-classname");
var cn_1 = require("../cn");
var flag_icon_1 = __importDefault(require("../flag-icon/flag-icon"));
var input_1 = __importDefault(require("../input/input"));
var select_1 = __importDefault(require("../select/select"));
var countries_1 = __importDefault(require("../lib/countries"));
var related_target_1 = __importDefault(require("../lib/related-target"));
var MAX_DIAL_CODE_LENGTH = 4;
/**
 * Компонент ввода международного телефона по маске.
 */
var IntlPhoneInput = /** @class */ (function (_super) {
    __extends(IntlPhoneInput, _super);
    function IntlPhoneInput() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.cn = bem_react_classname_1.createCn('intl-phone-input');
        _this.state = {
            countryIso2: 'ru',
            inputFocused: false,
            inputValue: _this.props.value,
            selectFocused: false,
            onceOpened: false,
        };
        _this.renderSelectButtonContent = function () { return _this.renderFlagIcon(_this.state.countryIso2); };
        _this.handleSelectFocus = function (event) {
            if (!_this.state.onceOpened) {
                _this.setState({
                    onceOpened: true,
                });
            }
            _this.resolveFocusedState({ selectFocused: true }, event);
        };
        _this.handleSelectButtonFocus = function () {
            _this.setState({
                selectFocused: true,
            });
        };
        _this.handleSelectBlur = function (event) {
            _this.resolveFocusedState({ selectFocused: false }, event);
        };
        _this.handleSelectButtonBlur = function (event) {
            _this.resolveFocusedState({ selectFocused: false }, event);
        };
        _this.handleSelectChange = function (value) {
            var inputValue = "+" + _this.countries.find(function (country) { return country.iso2 === value[0]; }).dialCode;
            _this.setState({
                countryIso2: value[0],
                inputValue: inputValue,
            }, function () {
                // Wait for select blur, then focus on input
                _this.timeoutId = setTimeout(function () {
                    _this.input.focus();
                    _this.input.setSelectionRange(inputValue.length);
                }, 0);
            });
        };
        _this.handleSelectClick = function () {
            // Set focus to input on select closing by it's button toggle
            if (_this.state.selectFocused) {
                _this.input.focus();
                _this.input.setSelectionRange(-1);
            }
        };
        _this.handleInputFocus = function (event) {
            _this.resolveFocusedState({ inputFocused: true }, event);
        };
        _this.handleInputBlur = function (event) {
            _this.resolveFocusedState({ inputFocused: false }, event);
        };
        _this.handleInputChange = function (value) {
            _this.setState({
                inputValue: value.length === 1 && value !== '+' ? "+" + value : value,
            }, _this.setCountry);
        };
        // TODO: торчит для теста
        _this.getOptions = function () {
            _this.countries = countries_1.default.getCountries();
            return _this.state.onceOpened ? _this.countries.map(function (country) { return ({
                value: country.iso2,
                text: (react_1.default.createElement("span", null,
                    country.name,
                    react_1.default.createElement("span", { className: _this.cn('select-option-code') },
                        "+",
                        country.dialCode))),
                nativeText: country.name + " +" + country.dialCode,
                icon: (react_1.default.createElement("span", { className: _this.cn('select-option-flag') }, _this.renderFlagIcon(country.iso2))),
            }); }) : [];
        };
        return _this;
    }
    IntlPhoneInput.prototype.componentDidMount = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.loadUtil()];
                    case 1:
                        _a.sent();
                        this.setCountry();
                        return [2 /*return*/];
                }
            });
        });
    };
    // eslint-disable-next-line camelcase
    IntlPhoneInput.prototype.UNSAFE_componentWillUpdate = function (nextProps, nextState) {
        if (this.state.inputValue !== nextState.inputValue) {
            if (this.props.onChange) {
                this.props.onChange(nextState.inputValue);
            }
        }
    };
    IntlPhoneInput.prototype.componentWillUnmount = function () {
        if (this.timeoutId) {
            clearTimeout(this.timeoutId);
            this.timeoutId = null;
        }
    };
    IntlPhoneInput.prototype.render = function () {
        var _this = this;
        return (react_1.default.createElement(input_1.default, __assign({ className: this.cn(), ref: function (input) {
                _this.input = input;
            } }, this.props, { focused: this.state.inputFocused || this.state.selectFocused, leftAddons: (react_1.default.createElement(select_1.default, { className: this.cn('select'), ref: function (select) {
                    _this.select = select;
                }, disabled: this.props.disabled, mode: "radio", options: this.getOptions(), popupSecondaryOffset: this.getSelectPopupOffset(), renderButtonContent: this.renderSelectButtonContent, size: this.props.size, value: [this.state.countryIso2], onBlur: this.handleSelectBlur, onChange: this.handleSelectChange, onClick: this.handleSelectClick, onFocus: this.handleSelectFocus, onButtonFocus: this.handleSelectButtonFocus, onButtonBlur: this.handleSelectButtonBlur })), noValidate: true, type: "tel", value: this.getValue(), onBlur: this.handleInputBlur, onChange: this.handleInputChange, onFocus: this.handleInputFocus })));
    };
    IntlPhoneInput.prototype.renderFlagIcon = function (countryIso2) {
        return (react_1.default.createElement(flag_icon_1.default, { country: countryIso2, mode: this.state.onceOpened ? 'sprite' : 'chunk', size: this.props.size }));
    };
    IntlPhoneInput.prototype.getSelectPopupOffset = function () {
        switch (this.props.size) {
            case 's': return -18;
            case 'm': return -24;
            case 'l': return -27;
            case 'xl': return -28;
        }
        return 0;
    };
    IntlPhoneInput.prototype.getValue = function () {
        // Use value from state not props, cause of some formatting steps in component
        // Sync props.value with state.inputValue in UNSAFE_componentWillUpdate
        return this.state.inputValue;
    };
    // TODO: торчит для теста
    IntlPhoneInput.prototype.loadUtil = function () {
        var _this = this;
        return Promise.resolve().then(function () { return __importStar(require(/* webpackChunkName: "libphonenumber" */ 'libphonenumber-js/bundle/libphonenumber-js.min')); }).then(function (util) {
            _this.util = util;
        })
            .catch(function (error) { return "An error occurred while loading libphonenumber-js:\n" + error; });
    };
    IntlPhoneInput.prototype.resolveFocusedState = function (nextFocusedStateItem, event) {
        var focusedState = {
            inputFocused: this.state.inputFocused,
            selectFocused: this.state.selectFocused,
        };
        var relatedTarget = related_target_1.default(event);
        var hasMatchedRelatedTarget = relatedTarget === event.target;
        var hasSelectRelatedTarget = false;
        var isSwitchBetweenRelatedTargers = false;
        // Check classNames matching in select's button (relatedTarget) & menu (focused target)
        if (relatedTarget.classList && event.target.classList) {
            hasSelectRelatedTarget = Array.from(relatedTarget.classList).some(function (item) { return /select/.test(item); })
                === Array.from(event.target.classList).some(function (item) { return /select/.test(item); });
            isSwitchBetweenRelatedTargers = !Object.values(focusedState).some(function (item) { return item; })
                && !Array.from(event.target.classList).some(function (item) { return /select/.test(item); })
                && Array.from(relatedTarget.classList).some(function (item) { return /select/.test(item); });
        }
        if (event.type === 'focus') {
            if (hasMatchedRelatedTarget || hasSelectRelatedTarget || isSwitchBetweenRelatedTargers) {
                // If we have smth already focused, do not do anything
                var alreadyInFocus = Object.values(focusedState).some(function (item) { return item; });
                if (!alreadyInFocus) {
                    this.setState(nextFocusedStateItem);
                    if (this.props.onFocus) {
                        this.props.onFocus(event);
                    }
                }
            }
        }
        if (event.type === 'blur') {
            if (!hasMatchedRelatedTarget) {
                // Set all values in focusedState to false cause we are blurring now
                this.setState(Object.keys(focusedState).reduce(function (result, item) {
                    result[item] = false;
                    return result;
                }, {}));
                if (this.props.onBlur) {
                    this.props.onBlur(event);
                }
            }
        }
    };
    IntlPhoneInput.prototype.setCountry = function () {
        var inputValue = this.getValue().replace(/ /g, '');
        for (var i = 0; i < this.countries.length; i++) {
            var country = this.countries[i];
            if (new RegExp("^\\+" + country.dialCode).test(inputValue)) {
                // Handle countries with priority field
                if (country.priority === undefined) {
                    this.setValue(country.iso2, inputValue);
                    break;
                }
                // Check max dial code length to allow country change
                // For countries with identical dial codes or North American Numbering Plan (NANP)
                if (inputValue.length < MAX_DIAL_CODE_LENGTH) {
                    // Update only value if countries are equal
                    if (this.state.countryIso2 === country.iso2) {
                        this.setValue(country.iso2, inputValue);
                        break;
                        // If not equal — set highest by priority
                    }
                    else if (country.priority === 0) {
                        this.setValue(country.iso2, inputValue);
                        break;
                    }
                    // Otherwise don't change already selected country, just set value
                }
                else if (this.state.countryIso2 === country.iso2) {
                    this.setValue(country.iso2, inputValue);
                    break;
                }
            }
        }
    };
    IntlPhoneInput.prototype.setValue = function (countryIso2, inputValue) {
        this.asYouType = this.util ? new this.util.AsYouType(countryIso2.toUpperCase()) : null;
        this.setState({
            inputValue: this.asYouType ? this.asYouType.input(inputValue) : inputValue,
            countryIso2: countryIso2,
        });
    };
    /**
     * Возвращает ссылку на HTMLElement инпута.
     */
    IntlPhoneInput.prototype.getControl = function () {
        return this.input.getControl();
    };
    /**
     * Устанавливает фокус на поле ввода.
     */
    IntlPhoneInput.prototype.focus = function () {
        this.input.focus();
    };
    /**
     * Убирает фокус с поля ввода.
     */
    IntlPhoneInput.prototype.blur = function () {
        this.input.blur();
    };
    /**
     * Скроллит страницу до поля ввода.
     */
    IntlPhoneInput.prototype.scrollTo = function () {
        this.input.scrollTo();
    };
    IntlPhoneInput.defaultProps = {
        size: 'm',
        value: '+7',
    };
    return IntlPhoneInput;
}(react_1.default.PureComponent));
exports.IntlPhoneInput = IntlPhoneInput;
exports.default = cn_1.withTheme(IntlPhoneInput);

//# sourceMappingURL=intl-phone-input.js.map
