import { createVNode, defineComponent, computed, shallowRef, watch, onBeforeUnmount, Fragment } from 'vue';
import { FilterFilled } from '@ant-design/icons-vue';
import '../../../../utils/index.mjs';
import { useInjectSlots } from '../context.mjs';
import { Button } from '../../../button/index.mjs';
import { Menu } from '../../../menu/index.mjs';
import { Checkbox } from '../../../checkbox/index.mjs';
import { Radio } from '../../../radio/index.mjs';
import { Dropdown } from '../../../dropdown/index.mjs';
import { Empty } from '../../../empty/index.mjs';
import useConfigInject from '../../../config-provider/src/hooks/useConfigInject.mjs';
import { Tree } from '../../../tree/index.mjs';
import FilterSearch from './FilterSearch.mjs';
import FilterDropdownMenuWrapper from './FilterWrapper.mjs';
import { flattenKeys } from './utils.mjs';
import { devWarning } from '../../../../utils/log.mjs';
import { isEqual } from '../../../../utils/is.mjs';
import { classNames } from '../../../../utils/dom/class.mjs';

const {
  SubMenu,
  Item: MenuItem
} = Menu;
function hasSubMenu(filters) {
  return filters.some(({
    children
  }) => children && children.length > 0);
}
function searchValueMatched(searchValue, text) {
  if (typeof text === "string" || typeof text === "number")
    return text == null ? void 0 : text.toString().toLowerCase().includes(searchValue.trim().toLowerCase());
  return false;
}
function renderFilterItems({
  filters,
  prefixCls,
  filteredKeys,
  filterMultiple,
  searchValue,
  filterSearch
}) {
  return filters.map((filter, index) => {
    const key = String(filter.value);
    if (filter.children) {
      return createVNode(SubMenu, {
        "key": key || index,
        "title": filter.text,
        "popupClassName": `${prefixCls}-dropdown-submenu`
      }, {
        default: () => [renderFilterItems({
          filters: filter.children,
          prefixCls,
          filteredKeys,
          filterMultiple,
          searchValue,
          filterSearch
        })]
      });
    }
    const Component = filterMultiple ? Checkbox : Radio;
    const item = createVNode(MenuItem, {
      "key": filter.value !== void 0 ? key : index
    }, {
      default: () => [createVNode(Component, {
        "checked": filteredKeys.includes(key)
      }, null), createVNode("span", null, [filter.text])]
    });
    if (searchValue.trim()) {
      if (typeof filterSearch === "function")
        return filterSearch(searchValue, filter) ? item : void 0;
      return searchValueMatched(searchValue, filter.text) ? item : void 0;
    }
    return item;
  });
}
var FilterDropdown = /* @__PURE__ */ defineComponent({
  name: "FilterDropdown",
  props: ["tablePrefixCls", "prefixCls", "dropdownPrefixCls", "column", "filterState", "filterMultiple", "filterMode", "filterSearch", "columnKey", "triggerFilter", "locale", "getPopupContainer"],
  setup(props, {
    slots
  }) {
    const contextSlots = useInjectSlots();
    const filterMode = computed(() => {
      var _a;
      return (_a = props.filterMode) != null ? _a : "menu";
    });
    const filterSearch = computed(() => {
      var _a;
      return (_a = props.filterSearch) != null ? _a : false;
    });
    const filterDropdownOpen = computed(() => props.column.filterDropdownOpen || props.column.filterDropdownVisible);
    const onFilterDropdownOpenChange = computed(() => props.column.onFilterDropdownOpenChange || props.column.onFilterDropdownVisibleChange);
    if (process.env.NODE_ENV !== "production") {
      [["filterDropdownVisible", "filterDropdownOpen", props.column.filterDropdownVisible], ["onFilterDropdownVisibleChange", "onFilterDropdownOpenChange", props.column.onFilterDropdownVisibleChange]].forEach(([deprecatedName, newName, prop]) => {
        devWarning(prop === void 0 || prop === null, "Table", `\`${deprecatedName}\` is deprecated. Please use \`${newName}\` instead.`);
      });
    }
    const visible = shallowRef(false);
    const filtered = computed(() => {
      var _a;
      return !!(props.filterState && (((_a = props.filterState.filteredKeys) == null ? void 0 : _a.length) || props.filterState.forceFiltered));
    });
    const filterFlattenKeys = computed(() => {
      var _a;
      return flattenKeys((_a = props.column) == null ? void 0 : _a.filters);
    });
    const filterDropdownRef = computed(() => {
      const {
        filterDropdown,
        slots: slots2 = {},
        customFilterDropdown
      } = props.column;
      return filterDropdown || slots2.filterDropdown && contextSlots.value[slots2.filterDropdown] || customFilterDropdown && contextSlots.value.customFilterDropdown;
    });
    const filterIconRef = computed(() => {
      const {
        filterIcon,
        slots: slots2 = {}
      } = props.column;
      return filterIcon || slots2.filterIcon && contextSlots.value[slots2.filterIcon] || contextSlots.value.customFilterIcon;
    });
    const triggerVisible = (newVisible) => {
      var _a;
      visible.value = newVisible;
      (_a = onFilterDropdownOpenChange.value) == null ? void 0 : _a.call(onFilterDropdownOpenChange, newVisible);
    };
    const mergedVisible = computed(() => typeof filterDropdownOpen.value === "boolean" ? filterDropdownOpen.value : visible.value);
    const propFilteredKeys = computed(() => {
      var _a;
      return (_a = props.filterState) == null ? void 0 : _a.filteredKeys;
    });
    const filteredKeys = shallowRef([]);
    const onSelectKeys = ({
      selectedKeys
    }) => {
      filteredKeys.value = selectedKeys;
    };
    const onCheck = (keys, {
      node,
      checked
    }) => {
      if (!props.filterMultiple)
        onSelectKeys({
          selectedKeys: checked && node.key ? [node.key] : []
        });
      else
        onSelectKeys({
          selectedKeys: keys
        });
    };
    watch(propFilteredKeys, () => {
      if (!visible.value)
        return;
      onSelectKeys({
        selectedKeys: propFilteredKeys.value || []
      });
    }, {
      immediate: true
    });
    const openKeys = shallowRef([]);
    const openRef = shallowRef();
    const onOpenChange = (keys) => {
      openRef.value = setTimeout(() => {
        openKeys.value = keys;
      });
    };
    const onMenuClick = () => {
      clearTimeout(openRef.value);
    };
    onBeforeUnmount(() => {
      clearTimeout(openRef.value);
    });
    const searchValue = shallowRef("");
    const onSearch = (e) => {
      const {
        value
      } = e.target;
      searchValue.value = value;
    };
    watch(visible, () => {
      if (!visible.value)
        searchValue.value = "";
    });
    const internalTriggerFilter = (keys) => {
      const {
        column,
        columnKey,
        filterState
      } = props;
      const mergedKeys = keys && keys.length ? keys : null;
      if (mergedKeys === null && (!filterState || !filterState.filteredKeys))
        return null;
      if (isEqual(mergedKeys, filterState == null ? void 0 : filterState.filteredKeys, true))
        return null;
      props.triggerFilter({
        column,
        key: columnKey,
        filteredKeys: mergedKeys
      });
    };
    const onConfirm = () => {
      triggerVisible(false);
      internalTriggerFilter(filteredKeys.value);
    };
    const onReset = ({
      confirm,
      closeDropdown
    } = {
      confirm: false,
      closeDropdown: false
    }) => {
      if (confirm)
        internalTriggerFilter([]);
      if (closeDropdown)
        triggerVisible(false);
      searchValue.value = "";
      if (props.column.filterResetToDefaultFilteredValue)
        filteredKeys.value = (props.column.defaultFilteredValue || []).map((key) => String(key));
      else
        filteredKeys.value = [];
    };
    const doFilter = ({
      closeDropdown
    } = {
      closeDropdown: true
    }) => {
      if (closeDropdown)
        triggerVisible(false);
      internalTriggerFilter(filteredKeys.value);
    };
    const onVisibleChange = (newVisible) => {
      if (newVisible && propFilteredKeys.value !== void 0) {
        filteredKeys.value = propFilteredKeys.value || [];
      }
      triggerVisible(newVisible);
      if (!newVisible && !filterDropdownRef.value)
        onConfirm();
    };
    const {
      direction
    } = useConfigInject("", props);
    const onCheckAll = (e) => {
      if (e.target.checked) {
        const allFilterKeys = filterFlattenKeys.value;
        filteredKeys.value = allFilterKeys;
      } else {
        filteredKeys.value = [];
      }
    };
    const getTreeData = ({
      filters
    }) => (filters || []).map((filter, index) => {
      const key = String(filter.value);
      const item = {
        title: filter.text,
        key: filter.value !== void 0 ? key : index
      };
      if (filter.children)
        item.children = getTreeData({
          filters: filter.children
        });
      return item;
    });
    const getFilterData = (node) => {
      var _a;
      return {
        ...node,
        text: node.title,
        value: node.key,
        children: ((_a = node.children) == null ? void 0 : _a.map((item) => getFilterData(item))) || []
      };
    };
    const treeData = computed(() => getTreeData({
      filters: props.column.filters
    }));
    const dropdownMenuClass = computed(() => classNames({
      [`${props.dropdownPrefixCls}-menu-without-submenu`]: !hasSubMenu(props.column.filters || [])
    }));
    const getFilterComponent = () => {
      const selectedKeys = filteredKeys.value;
      const {
        column,
        locale,
        tablePrefixCls,
        filterMultiple,
        dropdownPrefixCls,
        getPopupContainer,
        prefixCls
      } = props;
      if ((column.filters || []).length === 0) {
        return createVNode(Empty, {
          "image": Empty.PRESENTED_IMAGE_SIMPLE,
          "description": locale.filterEmptyText,
          "imageStyle": {
            height: 24
          },
          "style": {
            margin: 0,
            padding: "16px 0"
          }
        }, null);
      }
      if (filterMode.value === "tree") {
        return createVNode(Fragment, null, [createVNode(FilterSearch, {
          "filterSearch": filterSearch.value,
          "value": searchValue.value,
          "onChange": onSearch,
          "tablePrefixCls": tablePrefixCls,
          "locale": locale
        }, null), createVNode("div", {
          "class": `${tablePrefixCls}-filter-dropdown-tree`
        }, [filterMultiple ? createVNode(Checkbox, {
          "class": `${tablePrefixCls}-filter-dropdown-checkall`,
          "onChange": onCheckAll,
          "checked": selectedKeys.length === filterFlattenKeys.value.length,
          "indeterminate": selectedKeys.length > 0 && selectedKeys.length < filterFlattenKeys.value.length
        }, {
          default: () => [locale.filterCheckAll]
        }) : null, createVNode(Tree, {
          "checkable": true,
          "selectable": false,
          "blockNode": true,
          "multiple": filterMultiple,
          "checkStrictly": !filterMultiple,
          "class": `${dropdownPrefixCls}-menu`,
          "onCheck": onCheck,
          "checkedKeys": selectedKeys,
          "selectedKeys": selectedKeys,
          "showIcon": false,
          "treeData": treeData.value,
          "autoExpandParent": true,
          "defaultExpandAll": true,
          "filterTreeNode": searchValue.value.trim() ? (node) => {
            if (typeof filterSearch.value === "function")
              return filterSearch.value(searchValue.value, getFilterData(node));
            return searchValueMatched(searchValue.value, node.title);
          } : void 0
        }, null)])]);
      }
      return createVNode(Fragment, null, [createVNode(FilterSearch, {
        "filterSearch": filterSearch.value,
        "value": searchValue.value,
        "onChange": onSearch,
        "tablePrefixCls": tablePrefixCls,
        "locale": locale
      }, null), createVNode(Menu, {
        "multiple": filterMultiple,
        "prefixCls": `${dropdownPrefixCls}-menu`,
        "class": dropdownMenuClass.value,
        "onClick": onMenuClick,
        "onSelect": onSelectKeys,
        "onDeselect": onSelectKeys,
        "selectedKeys": selectedKeys,
        "getPopupContainer": getPopupContainer,
        "openKeys": openKeys.value,
        "onOpenChange": onOpenChange
      }, {
        default: () => renderFilterItems({
          filters: column.filters || [],
          filterSearch: filterSearch.value,
          prefixCls,
          filteredKeys: filteredKeys.value,
          filterMultiple,
          searchValue: searchValue.value
        })
      })]);
    };
    const resetDisabled = computed(() => {
      const selectedKeys = filteredKeys.value;
      if (props.column.filterResetToDefaultFilteredValue) {
        return isEqual((props.column.defaultFilteredValue || []).map((key) => String(key)), selectedKeys, true);
      }
      return selectedKeys.length === 0;
    });
    return () => {
      var _a;
      const {
        tablePrefixCls,
        prefixCls,
        column,
        dropdownPrefixCls,
        locale,
        getPopupContainer
      } = props;
      let dropdownContent;
      if (typeof filterDropdownRef.value === "function") {
        dropdownContent = filterDropdownRef.value({
          prefixCls: `${dropdownPrefixCls}-custom`,
          setSelectedKeys: (selectedKeys) => onSelectKeys({
            selectedKeys
          }),
          selectedKeys: filteredKeys.value,
          confirm: doFilter,
          clearFilters: onReset,
          filters: column.filters,
          visible: mergedVisible.value,
          column: column.__originColumn__,
          close: () => {
            triggerVisible(false);
          }
        });
      } else if (filterDropdownRef.value) {
        dropdownContent = filterDropdownRef.value;
      } else {
        dropdownContent = createVNode(Fragment, null, [getFilterComponent(), createVNode("div", {
          "class": `${prefixCls}-dropdown-btns`
        }, [createVNode(Button, {
          "type": "link",
          "size": "small",
          "disabled": resetDisabled.value,
          "onClick": () => onReset()
        }, {
          default: () => [locale.filterReset]
        }), createVNode(Button, {
          "type": "primary",
          "size": "small",
          "onClick": onConfirm
        }, {
          default: () => [locale.filterConfirm]
        })])]);
      }
      const menu = createVNode(FilterDropdownMenuWrapper, {
        "class": `${prefixCls}-dropdown`
      }, {
        default: () => [dropdownContent]
      });
      let filterIcon;
      if (typeof filterIconRef.value === "function") {
        filterIcon = filterIconRef.value({
          filtered: filtered.value,
          column: column.__originColumn__
        });
      } else if (filterIconRef.value) {
        filterIcon = filterIconRef.value;
      } else {
        filterIcon = createVNode(FilterFilled, null, null);
      }
      return createVNode("div", {
        "class": `${prefixCls}-column`
      }, [createVNode("span", {
        "class": `${tablePrefixCls}-column-title`
      }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), createVNode(Dropdown, {
        "overlay": menu,
        "trigger": ["click"],
        "open": mergedVisible.value,
        "onOpenChange": onVisibleChange,
        "getPopupContainer": getPopupContainer,
        "placement": direction.value === "rtl" ? "bottomLeft" : "bottomRight"
      }, {
        default: () => [createVNode("span", {
          "role": "button",
          "tabindex": -1,
          "class": classNames(`${prefixCls}-trigger`, {
            active: filtered.value
          }),
          "onClick": (e) => {
            e.stopPropagation();
          }
        }, [filterIcon])]
      })]);
    };
  }
});

export { FilterDropdown as default };
//# sourceMappingURL=FilterDropdown.mjs.map
