"use strict";

exports.__esModule = true;
exports.default = void 0;

var _react = _interopRequireWildcard(require("react"));

var _clsx = _interopRequireDefault(require("clsx"));

var _icons = require("@react-vant/icons");

var _utils = require("../utils");

var _hooks = require("../hooks");

var _tabs = _interopRequireDefault(require("../tabs"));

var _ConfigProviderContext = _interopRequireDefault(require("../config-provider/ConfigProviderContext"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

/* eslint-disable no-plusplus */
var INITIAL_STATE = {
  tabs: [],
  activeTab: 0
};

var Cascader = function Cascader(props) {
  var _useContext = (0, _react.useContext)(_ConfigProviderContext.default),
      prefixCls = _useContext.prefixCls,
      createNamespace = _useContext.createNamespace,
      locale = _useContext.locale;

  var _createNamespace = createNamespace('cascader', prefixCls),
      bem = _createNamespace[0];

  var _useState = (0, _react.useState)(undefined),
      internalValue = _useState[0],
      updateInternalValue = _useState[1];

  var _useSetState = (0, _hooks.useSetState)(INITIAL_STATE),
      state = _useSetState[0],
      updateState = _useSetState[1];

  var _extend = (0, _utils.extend)({
    text: 'text',
    value: 'value',
    children: 'children'
  }, props.fieldNames),
      textKey = _extend.text,
      valueKey = _extend.value,
      childrenKey = _extend.children;

  var getSelectedOptionsByValue = function getSelectedOptionsByValue(options, value) {
    for (var i = 0; i < options.length; i++) {
      var option = options[i];

      if (option[valueKey] === value) {
        return [option];
      }

      if (option[childrenKey]) {
        var selectedOptions = getSelectedOptionsByValue(option[childrenKey], value);

        if (selectedOptions) {
          return [option].concat(selectedOptions);
        }
      }
    }

    return undefined;
  };

  var updateTabs = function updateTabs() {
    if (internalValue || internalValue === 0) {
      var selectedOptions = getSelectedOptionsByValue(props.options, internalValue);

      if (selectedOptions) {
        var optionsCursor = props.options;
        var tabs = selectedOptions.map(function (option) {
          var tab = {
            options: optionsCursor,
            selectedOption: option
          };
          var next = optionsCursor.find(function (item) {
            return item[valueKey] === option[valueKey];
          });

          if (next) {
            optionsCursor = next[childrenKey];
          }

          return tab;
        });

        if (optionsCursor) {
          tabs.push({
            options: optionsCursor,
            selectedOption: null
          });
        }

        updateState({
          tabs: tabs
        });
        setTimeout(function () {
          updateState({
            activeTab: tabs.length - 1
          });
        }, 0);
        return;
      }
    }

    updateState({
      tabs: [{
        options: props.options,
        selectedOption: null
      }]
    });
  };

  var onSelect = function onSelect(option, tabIndex) {
    if (option.disabled) {
      return;
    }

    var tabs = JSON.parse(JSON.stringify(state.tabs));
    tabs[tabIndex].selectedOption = option;

    if (tabs.length > tabIndex + 1) {
      tabs = tabs.slice(0, tabIndex + 1);
    }

    if (option[childrenKey]) {
      var nextTab = {
        options: option[childrenKey],
        selectedOption: null
      };

      if (tabs[tabIndex + 1]) {
        tabs[tabIndex + 1] = nextTab;
      } else {
        tabs.push(nextTab);
      }

      updateState({
        tabs: tabs,
        activeTab: state.activeTab + 1
      });
    }

    var selectedOptions = tabs.map(function (tab) {
      return tab.selectedOption;
    }).filter(Boolean);
    var eventParams = {
      value: option[valueKey],
      tabIndex: tabIndex,
      selectedOptions: selectedOptions
    };
    updateInternalValue(option[valueKey]);
    props.onChange == null ? void 0 : props.onChange(eventParams);

    if (!option[childrenKey]) {
      props.onFinish == null ? void 0 : props.onFinish(eventParams);
    }
  };

  var onClose = function onClose() {
    return props.onClose == null ? void 0 : props.onClose();
  };

  var onClickTab = function onClickTab(_ref) {
    var name = _ref.name,
        title = _ref.title;
    updateState({
      activeTab: +name
    });
    props.onClickTab == null ? void 0 : props.onClickTab(+name, title);
  };

  var getStateFromValue = function getStateFromValue(value) {
    if (!value || !value.length) return INITIAL_STATE;

    try {
      var initialState = {
        activeTab: value.length - 1,
        tabs: []
      };
      value.reduce(function (options, v) {
        var selectedOption = options.find(function (tabs) {
          return tabs[valueKey] === v;
        });
        if (!selectedOption) throw Error('Cascader: unable to match options correctly, Please check value or defaultValue props.');
        initialState.tabs.push({
          options: options,
          selectedOption: selectedOption
        });
        return selectedOption[childrenKey];
      }, props.options);
      return initialState;
    } catch (error) {
      // eslint-disable-next-line no-console
      console.error(error);
      return INITIAL_STATE;
    }
  };

  var renderCloseIcon = function renderCloseIcon() {
    if (!props.closeable) return null;

    if (props.closeIcon) {
      return /*#__PURE__*/_react.default.cloneElement(props.closeIcon, {
        className: (0, _clsx.default)(bem('close-icon')),
        onClick: onClose
      });
    }

    return /*#__PURE__*/_react.default.createElement(_icons.Cross, {
      className: (0, _clsx.default)(bem('close-icon')),
      onClick: onClose
    });
  };

  var renderHeader = function renderHeader() {
    return /*#__PURE__*/_react.default.createElement("div", {
      className: (0, _clsx.default)(bem('header'))
    }, /*#__PURE__*/_react.default.createElement("h2", {
      className: (0, _clsx.default)(bem('title'))
    }, props.title), renderCloseIcon());
  };

  var renderOption = function renderOption(option, selectedOption, tabIndex) {
    var selected = selectedOption && option[valueKey] === selectedOption[valueKey];
    var color = option.color || (selected ? props.activeColor : undefined);
    var Text = props.optionRender ? props.optionRender({
      option: option,
      selected: selected
    }) : /*#__PURE__*/_react.default.createElement("span", null, option[textKey]);
    return /*#__PURE__*/_react.default.createElement("li", {
      key: option[valueKey],
      className: (0, _clsx.default)(bem('option', {
        selected: selected,
        disabled: option.disabled
      }), option.className),
      style: {
        color: color
      },
      onClick: function onClick() {
        return onSelect(option, tabIndex);
      }
    }, Text, selected ? /*#__PURE__*/_react.default.createElement(_icons.Success, {
      className: (0, _clsx.default)(bem('selected-icon'))
    }) : null);
  };

  var renderOptions = function renderOptions(options, selectedOption, tabIndex) {
    return /*#__PURE__*/_react.default.createElement("ul", {
      key: tabIndex,
      className: (0, _clsx.default)(bem('options'))
    }, options.map(function (option) {
      return renderOption(option, selectedOption, tabIndex);
    }));
  };

  var renderTab = function renderTab(tab, tabIndex) {
    var options = tab.options,
        selectedOption = tab.selectedOption;
    var title = selectedOption ? selectedOption[textKey] : props.placeholder || locale.vanCascader.select;
    return /*#__PURE__*/_react.default.createElement(_tabs.default.TabPane, {
      key: tabIndex,
      title: title,
      titleClass: (0, _clsx.default)(bem('tab', {
        unselected: !selectedOption
      }))
    }, renderOptions(options, selectedOption, tabIndex));
  };

  var renderTabs = function renderTabs() {
    return /*#__PURE__*/_react.default.createElement(_tabs.default, {
      animated: true,
      active: state.activeTab,
      className: (0, _clsx.default)(bem('tabs')),
      color: props.activeColor,
      swipeThreshold: 0,
      swipeable: props.swipeable,
      onClickTab: onClickTab
    }, state.tabs.map(renderTab));
  };

  (0, _react.useEffect)(function () {
    updateTabs();
  }, [JSON.stringify(props.options)]);
  (0, _react.useEffect)(function () {
    var _props$value;

    var value = (_props$value = props.value) != null ? _props$value : props.defaultValue;
    if (!value || Array.isArray(value) && !value.length) return;
    var initialState = getStateFromValue(value);
    updateState(initialState);
  }, []);
  (0, _hooks.useUpdateEffect)(function () {
    var initialState = getStateFromValue(props.value);
    updateState(initialState);
  }, [props.value]);
  (0, _hooks.useUpdateEffect)(function () {
    if (internalValue || internalValue === 0) {
      var values = state.tabs.map(function (tab) {
        var _tab$selectedOption;

        return (_tab$selectedOption = tab.selectedOption) == null ? void 0 : _tab$selectedOption[valueKey];
      });

      if (values.includes(internalValue)) {
        return;
      }
    }

    updateTabs();
  }, [internalValue]);
  return /*#__PURE__*/_react.default.createElement("div", {
    className: (0, _clsx.default)(bem())
  }, renderHeader(), state.tabs.length ? renderTabs() : null);
};

Cascader.defaultProps = {
  closeable: true,
  swipeable: true,
  options: []
};
var _default = Cascader;
exports.default = _default;