import React, { useState, useEffect } from 'react';
import { Cascader, Select, Button } from 'antd';
import { YIcon } from '../icon';
import { CascaderOptionType, CascaderProps } from 'antd/lib/cascader';
import { SelectProps } from 'antd/lib/select';
import {
  YGoodsCategoriesProps,
  GoodsCategoriesCascaderModeOption,
  GoodsCategoriesValueItem,
} from './goodsCategories.interface';
import { DEF_PARENTNO } from './goodsCategories.config';
import { markReturnDataStructure } from './goodsCategories.utils';
import { useModel } from './useModel';

const { Option } = Select;
// 类目缓存数组
const categoriesDataCache: any = {};

export const GoodsCategoriesCascader: React.FC<YGoodsCategoriesProps<any>> = (
  props,
) => {
  const { config, onChange, originalProps } = props;
  const { getCategoryList } = useModel();
  const parentNo: string = config.parentNo ? config.parentNo : DEF_PARENTNO;
  const [cascaderOptions, setCascaderOptions] = useState([]);
  const [multipleSelectItems, setMultipleSelectItems] = useState<any>([]);
  const [multipleSelectKey, setMultipleSelectKey] = useState(
    'multipleSelectKey_def',
  );
  const [multipleSelectDefValue, setMultipleSelectDefValue] = useState([]);

  /* Cascader动态数据加载 */
  const loadCascaderData: any = (selectedOptions: CascaderOptionType[]) => {
    const targetOption = selectedOptions[selectedOptions.length - 1];
    targetOption.loading = true;

    getCategoryData(targetOption.value as string, (resData: any) => {
      targetOption.loading = false;
      if (resData) {
        targetOption.children = [];
        targetOption.children = resData;
        setCascaderOptions([...cascaderOptions]);
      }
    });
  };

  // get Category Data
  const getCategoryData = async (
    parentNo: string,
    callback: { (data: any): void; (arg0: any): any },
  ) => {
    const res: any = await getCategoryList({
      parentNo: parentNo,
    });
    const tempData: GoodsCategoriesCascaderModeOption[] = [];
    res &&
      res.map(
        (item: { categoryNo: any; categoryName: any; hasChild: number }) => {
          let tData = {
            value: item.categoryNo,
            label: item.categoryName,
            orgData: JSON.stringify(item),
            isLeaf: item.hasChild === 0 ? true : false,
          };
          tempData.push(tData);
          categoriesDataCache[item.categoryNo] = tData;
        },
      );
    callback && callback(tempData);
  };

  /* Actions */
  /* selected Item Callback */
  const cascaderOnChange = (values: any, items: any) => {
    let itemsDetail: GoodsCategoriesValueItem[] = [];
    values &&
      values.length &&
      items &&
      items.map((item: { orgData: string }) => {
        itemsDetail.push(
          markReturnDataStructure(
            JSON.parse(item.orgData),
          ) as GoodsCategoriesValueItem,
        );
      });
    onChange(itemsDetail);
  };

  /* muliple Mode Actions */
  const mulipleCascaderOnChange = (_values: any, items: any) => {
    let tData: any = [];
    multipleSelectItems &&
      multipleSelectItems.length &&
      multipleSelectItems.map((item: any) => {
        tData.push(item);
      });

    let tempData: any = {
      value: '',
      key: '',
      label: '',
    };
    for (let i = 0; i < items.length; i++) {
      tempData.value =
        tempData.value +
        (i === items.length - 1 ? `${items[i].value}` : `${items[i].value}_`);
      tempData.key =
        tempData.key +
        (i === items.length - 1 ? `${items[i].value}` : `${items[i].value}_`);
      tempData.label =
        tempData.label +
        (i === items.length - 1 ? `${items[i].label}` : `${items[i].label}/`);
    }

    let hasKey = false;
    // selected values && Prevent repeated selection
    let _tMultipleSelectValues: any = [];
    for (let i = 0; i < tData.length; i++) {
      if (tData[i].key !== '' && tData[i].key === tempData.key) {
        hasKey = true;
      }
      _tMultipleSelectValues.push(tData[i].key);
    }

    if (!hasKey) {
      tData.push(tempData);
      _tMultipleSelectValues.push(tempData.key);
      // selected key
      setMultipleSelectKey(`multipleSelectKey_${tempData.key}`);
      // selected values
      setMultipleSelectDefValue(_tMultipleSelectValues);
      setMultipleSelectItems(tData);
      // run components Callback
      mulipleSelectedOnChange(_tMultipleSelectValues);
    }
  };

  const mulipleSelectedOnChange = (items: any) => {
    const retData: any = [];
    items.map((item: string, index: number) => {
      let ids = item.split('_');
      retData[index] = [];
      ids.map((id: string) => {
        retData[index].push(
          markReturnDataStructure(JSON.parse(categoriesDataCache[id].orgData)),
        );
      });
    });
    onChange(retData);
  };

  const selectOnChange = (value: any) => {
    let newData: any = [];
    for (let i = 0; i < multipleSelectItems.length; i++) {
      for (let j = 0; j < value.length; j++) {
        if (multipleSelectItems[i].key === value[j].key) {
          newData.push(multipleSelectItems[i]);
        }
      }
    }
    mulipleSelectedOnChange(value);
    setMultipleSelectItems(newData);
    setMultipleSelectDefValue(value);
  };

  // Loaded
  useEffect(() => {
    getCategoryData(parentNo, (data: React.SetStateAction<never[]>) => {
      setCascaderOptions(data);
    });
  }, []);

  return (
    <>
      {/* 单选 */}
      {!config.multiple && (
        <Cascader
          {...(originalProps as CascaderProps)}
          expandTrigger="hover"
          options={cascaderOptions}
          loadData={loadCascaderData}
          onChange={cascaderOnChange}
        />
      )}
      {/* 多选 */}
      {config.multiple && (
        <>
          <Select
            {...(originalProps as SelectProps<any>)}
            defaultValue={multipleSelectDefValue}
            key={multipleSelectKey}
            mode="multiple"
            dropdownStyle={{ visibility: 'hidden' }}
            onChange={selectOnChange}
          >
            {multipleSelectItems &&
              multipleSelectItems.map(
                (tItem: { key: string; label: string; value: string }) => (
                  <Option key={tItem.key} value={tItem.value}>
                    {tItem.label}
                  </Option>
                ),
              )}
          </Select>

          <Cascader
            options={cascaderOptions}
            loadData={loadCascaderData}
            onChange={mulipleCascaderOnChange}
            expandTrigger="hover"
          >
            <Button
              style={{ marginLeft: '10px' }}
              {...config.multipleConfig.btnConfig}
            >
              {/* <PlusOutlined style={{ marginRight: '6px' }} /> */}
              <YIcon name="PlusOutlined" style={{ marginRight: '6px' }} />
              {config.multipleConfig.addBtnLabel &&
              config.multipleConfig.addBtnLabel !== ''
                ? config.multipleConfig.addBtnLabel
                : '选择类目添加'}
            </Button>
          </Cascader>
        </>
      )}
    </>
  );
};
