import {
  DICTIONARY_CHILDLIST,
  USER_CENTER_COMPANY_MANAGE_LIST,
} from '@/services/Urls';
import { getTableData } from '@/services/common/components';
import { getRequest } from '@/services/common/role';
import type { ProColumns } from '@ant-design/pro-components';
import { ProTable } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Empty, Space, Table, Typography } from 'antd';
import React, { useEffect, useRef, useState } from 'react';

type TableListItem = {
  [key: string]: any;
};
type ableType = {
  id: number; //id标识
  status: boolean;
  type: string;
};
type SearchTableType = {
  columns: ProColumns<TableListItem>[];
  initAPI: string;
  headerTitle: string;
  rowKey: string;
  reload: number;
  toolbar?: object;
  toolBarRender?: () => React.ReactNode[];
  expandChildrenColumnName?: string;
  isMass?: boolean;
  setMassIds?: (ids: (string | number)[]) => void;
  expandedRowRender?: (record: any) => JSX.Element;
  otherParams?: object;
  selectedValue?: (value: any) => void;
  selectParams?: (value: any) => void;

  getCheckboxProps?: (record: any) => any;
  roleType?: string | number;
  pageSize?: number;
  sortType?: ableType; //{id,type}
  scrollX?: string | number;
  disableEnable?: ableType; //{id,status}
  isSerial?: boolean;
  isChildExpand?: boolean;
  onExpandType?: string;
  lastTable?: boolean;
  searchParams?: any;
  
  listItem?: TableListItem;
  setListItem?: (value: any) => void;
  reloadChildren?: number;
  expandedRowKeys: string[];
  setExpandedRowKeys: (value: any) => void;
  isDelClick?: boolean;
  setIsDelClick?: (value: any) => void;
  onResetSearch?: () => void;
};

const CompanyTable = ({
  columns,
  initAPI,
  headerTitle,
  rowKey,
  reload,
  toolbar,
  toolBarRender,
  expandChildrenColumnName = 'children',
  isMass,
  setMassIds,
  expandedRowRender,
  otherParams,
  searchParams,
  selectedValue,
  selectParams,
  getCheckboxProps,
  pageSize,
  scrollX,
  sortType,
  disableEnable,
  isSerial,
  isChildExpand,
  onExpandType,
  lastTable,
  listItem,
  setListItem,
  reloadChildren,
  expandedRowKeys,
  setExpandedRowKeys,
  isDelClick,
  setIsDelClick,
  onResetSearch
}: SearchTableType) => {
  const intl = useIntl();
  const [customColumns, setCustomColumns] = useState<any>();
  const [tableData, setTableData] = useState<any>([]);
  const [searchText, setSearchText] = useState<any>();
  const [relationship, setRelationship] = useState<any>([
    { id: '0', children: [] },
  ]);
  const [obj, setObj] = useState<any>();
  const [tableDataChild, setTableDataChild] = useState<any>([]);

  // 操作表格
  const tableRef: React.MutableRefObject<any> = useRef();

  // 递归处理带子项child的表格，没数据将child转为null，防止出现空展开的图标
  const extractChildren = (arr: any) => {
    return arr.map((item: any) => {
      if (item.child && item.child.length === 0) {
        item.child = null;
      } else if (item.child && item.child.length > 0) {
        item.child = extractChildren(item.child);
      }
      return item;
    });
  };

  //判断数据是否为最后一位
  const markLastItem = (items: any) => {
    items.forEach((item: any, index: any, array: any) => {
      item.finally = index === array.length - 1;
      if (item[expandChildrenColumnName]) {
        markLastItem(item[expandChildrenColumnName]);
      }
    });
  };

  const childrenList = (arr: any, list: any) => {
    let arrData: any = [...arr];
    let listArr: any = [...list];
    arrData = arrData.map((item: any) => {
      listArr.push(item.deptId);
      if (item.children && item.children.length === 0) {
        item.routes = null;
      } else if (item.children && item.children.length > 0) {
        [item.routes, listArr] = childrenList(item.children, listArr);
      }
      return item;
    });
    return [arrData,listArr];
  };

  // 封装表格类 网络请求
  const getTable: any = async (params: {
    pageSize: number;
    current: number;
    deptName?: string;
    queryParams?: string;
  }) => {
    const req: any = {
      ...otherParams,
      ...params,
      ...searchParams,
      pageSize: pageSize || params.pageSize,
      pageNum: params.current,
    };
    setExpandedRowKeys([]);
    setSearchText(searchParams?.deptName || undefined);

    if (rowKey === 'deptId') {
      req.deptId = 0;
    }
    if (selectParams) selectParams(req);
    delete req.current;
    if (searchParams?.deptName) {
      delete req.deptId;
    }
    const resp = await getTableData(initAPI, req);
    let dataItems: any[];
    if (isSerial) {
      if (isChildExpand) {
        const data = resp.data.items.map((item: any, index: number) => ({
          ...item,
          orderIndex: index + 1 + (params.current - 1) * params.pageSize,
        }));
        dataItems = extractChildren(data);
      } else {
        dataItems = resp.data.items.map((item: any, index: number) => ({
          ...item,
          orderIndex: index + 1 + (params.current - 1) * params.pageSize,
        }));
      }
    } else {
      dataItems = resp.data.items;
    }
    let list: any = [];
    dataItems = dataItems.map((item: any) => {
      list.push(item.deptId);
      if (item.children && item.children.length){
        [item.routes, list] = childrenList(item.children, list);
        setExpandedRowKeys([...expandedRowKeys, ...list]);
      }else if ((item.hasChildren === 1 && !item.routes) && !item.children) {
        item.routes = [];
      }
      return { ...item };
    });
    
    // const dataItems = resp.data.items;
    if (lastTable) markLastItem(dataItems);
    setTableData(dataItems);
    // dataItems.forEach(item => {
    //   setStatusFalseInit(dataItems, item[rowKey]);
    // });
    return {
      data: dataItems,
      success: true,
      total: resp.data.totalCount,
    };
  };

  //禁用/启用子级逻辑
  const setRoutesStatus = (routes: any, status: any) => {
    routes.forEach((route: any) => {
      route.status = status;
      route.disableParent=status;
      if (route[expandChildrenColumnName]) {
        setRoutesStatus(route[expandChildrenColumnName], status);
      }
    });
  };
  
  //禁用/启用父级逻辑
  const setStatusFalseInit = (items: any, id: number) => {
    if (setListItem) setListItem(undefined);
    const newItems = [...items];
    items.forEach((item: any) => {
      if (item[rowKey] === id) {
        if (item[expandChildrenColumnName]) {
          setRoutesStatus(item[expandChildrenColumnName], item.status);
        }
      } else if (item[expandChildrenColumnName]) {
        setStatusFalseInit(item[expandChildrenColumnName], id);
      }
    });
    setTableData(newItems);
  };

  //禁用/启用父级逻辑
  const setStatusFalse = (items: any, id: number) => {
    if (setListItem) setListItem(undefined);
    const newItems = [...items];
    items.forEach((item: any) => {
      if (item[rowKey] === id) {
        item.status = !item.status;
        if (item[expandChildrenColumnName]) {
          setRoutesStatus(item[expandChildrenColumnName], item.status);
        }
      } else if (item[expandChildrenColumnName]) {
        setStatusFalse(item[expandChildrenColumnName], id);
      }
    });
    setTableData(newItems);
  };

  //排序逻辑
  const sortMenu = (items: any, id: number, type: string) => {
    const targetIndex = items.findIndex((item: any) => item[rowKey] === id);
    if (targetIndex === -1) {
      return items.map((item: any) =>
        item[expandChildrenColumnName]
          ? {
              ...item,
              [expandChildrenColumnName]: sortMenu(
                item[expandChildrenColumnName],
                id,
                type,
              ),
            }
          : item,
      );
    }
    const targetItem = items[targetIndex];
    const restItems = items.filter(
      (_: any, index: any) => index !== targetIndex,
    );

    switch (type) {
      case 'top':
        return [targetItem].concat(restItems);
      case 'bottom':
        return restItems.concat([targetItem]);
      case 'prev':
        return targetIndex === 0
          ? items
          : [
              ...restItems.slice(0, targetIndex - 1),
              targetItem,
              items[targetIndex - 1],
              ...restItems.slice(targetIndex),
            ];
      case 'next':
        return targetIndex === items.length - 1
          ? items
          : [
              ...restItems.slice(0, targetIndex),
              items[targetIndex + 1],
              targetItem,
              ...restItems.slice(targetIndex + 1),
            ];
      default:
        return items;
    }
  };
  const getAllChild = (tree: any, arr: any[]) => {
    tree.forEach((item: any) => {
      arr.push(item.id);
      if (item.children?.length) {
        getAllChild(item.children, arr);
      }
    });
  };
  const getAllChildId = (data: any, key: any, arr: any[]) => {
    for (let i = 0; i < data.length; i++){
      if (data[i].id === key) {
        arr.push(key);
        getAllChild(data[i].children, arr);
        break;
      }
      if (data[i].children?.length) {
        getAllChildId(data[i].children, key, arr);
      }
    }
  };

  const setChildrenFalse = (idStr: any, items: any, id: any, recordList: any) => {
    const newItems = [...items];
    newItems.forEach((item: any) => {
      if (item[rowKey] === id) {
        if ((recordList && expandedRowKeys) && item.routes) {
          let list: string[] = [...expandedRowKeys];
          item.routes = item.routes.map((record: any) => {
            // if (record.hasChildren === 1) {
            //   console.log(4);
            //   record.routes = [];
            // }
            expandedRowKeys.forEach((key) => {
              if (record[rowKey] === key) {
                // console.log(relationship);
                let arr: any[] = [];
                getAllChildId(relationship, key, arr);
                // console.log(arr);
                arr.forEach((item) => {
                  list = [...list.filter((record) => record !== item)];
                });
                // list = [...list.filter((record) => record !== key)];
              }
              // if (record['parentId'] === key){
              //   list = [...list.filter(record=>record!==key)];
              // }
            });
            return { ...record };
          });
          if (setExpandedRowKeys) {
            setExpandedRowKeys([...list]);
          }
        }
        if (tableDataChild.length && !searchText) {
          if (idStr !== 'parentId') {
            // eslint-disable-next-line no-param-reassign
            tableDataChild.map((sub: any) => {
              if (sub.hasChildren === 1) {
                sub.routes = [];
              }
              return {...sub};
            });
          } else if (recordList) {
            // eslint-disable-next-line no-param-reassign
            tableDataChild.map((sub: any) => {
              // console.log(sub[rowKey], recordList[rowKey], recordList);
              // if (sub[rowKey] === recordList[rowKey] && recordList.routes) {
              //   // sub.routes = [...recordList.routes];
              //   sub.routes = [];
              // } else if (sub.hasChildren === 1) {
              //   sub.routes = [];
              // }
              if (sub.hasChildren === 1) {
                sub.routes = [];
              }
              return {...sub};
            });
          }
          item.routes = tableDataChild;
        } else if (searchText) {
          tableDataChild[0].children.map((sub: any) => {
            if (sub.hasChildren === 1) {
              sub.routes = [];
            }
            return {...sub};
          });
          item.routes = tableDataChild;
          setSearchText(null);
        } else if (!tableDataChild.length) {
          delete item.routes;
        }
      } else if (item[expandChildrenColumnName] && item[expandChildrenColumnName].length>0) {
        setChildrenFalse(idStr, item[expandChildrenColumnName], id, recordList);
      }
    });
    setTableDataChild(null);
    setObj(null);
    markLastItem(newItems);
    setTableData(newItems);
    if (setListItem) setListItem(undefined);
    
  };
  const handleParentData = (data:any, record:any) => {
    let newItems = [...tableData];
    tableData.forEach((item: any) => {
      if (item[rowKey] === record[rowKey]) {
        data.forEach((res: any) => {
          if (res[rowKey] === item[rowKey]) {
            if (onExpandType === 'company') {
              item.deptName = res.deptName;
              item.status = res.status;
              item.remark = res.remark;
            } else if (onExpandType === 'dictionaries')  {
              item.dictLabel = res.dictLabel;
              item.status = res.status;
              item.dictValue = res.dictValue;
            }
            if (res.hasChildren === 1) {
              item.routes = [];
            }
          }
        });
        if (setExpandedRowKeys && expandedRowKeys) {
          setExpandedRowKeys([
            ...expandedRowKeys.filter((record) => record !== item[rowKey]),
          ]);
          if (setListItem) setListItem(undefined);
        }
      }
    });
    setTableData([
      ...newItems.filter((record: any) =>
        data.some((obj: any) => obj[rowKey] === record[rowKey]),
      ),
    ]);
  };
  const addOrDelChildren = (record: TableListItem, url: string, id: string) => {
    // if (id === 'parentId' && (record[id] === '0' || record[id] === 0)){
    //   tableRef.current.reload();
    //   return;
    // }
    let itemId: any = record[id];
    let obj:any = {};
    if(searchText && onExpandType === 'company'){
      obj.deptName = searchText;
    }
    if (record[id] === '0') {
      getRequest(url, { [rowKey]: 0, ...obj }).then((res) => {
        if (onExpandType === 'company') {
          handleParentData(res.data.items, record);
        } else if (onExpandType === 'dictionaries') {
          handleParentData(res.data, record);
        }
        itemId = record[rowKey];
      });
      if (isDelClick && setIsDelClick) {
        setIsDelClick(false);
        return;
      }
    }else{
      getRequest(url, { [rowKey]: itemId, ...obj }).then((res) => {
        if (onExpandType === 'company') {
          setTableDataChild(res.data.items);
          setObj({
            idStr: id === rowKey || record[id] === '0' ? rowKey : id,
            items: tableData,
            id: record[id],
            recordList: listItem
          });
        } else if (onExpandType === 'dictionaries') {
          setTableDataChild(res.data);
          setObj({
            idStr: id === rowKey || record[id] === '0' ? rowKey : id,
            items: tableData,
            id: record[id],
            recordList: listItem
          });
          // setChildrenFalse(
          //   id === rowKey || record[id] === '0' ? rowKey : id,
          //   tableData,
          //   record[id],
          // );
        }
        setStatusFalseInit(tableData, record[rowKey]);
      });
    }
  };

  const getChildren = (
    is: boolean,
    record: TableListItem,
    url: string,
    id: string,
  ) => {
    if (is && record?.routes.length === 0) {
      addOrDelChildren(record, url, id);
    }
  };

  const expandSwitch = (is: boolean, record: TableListItem, type: string) => {
    switch (type) {
      case 'dictionaries':
        getChildren(is, record, DICTIONARY_CHILDLIST, 'dictId');
        break;
      case 'company':
        getChildren(is, record, USER_CENTER_COMPANY_MANAGE_LIST, 'deptId');
        break;
      default:
        return null;
    }
  };
  const setRelationshipTree = (data: any, item: any) => {
    for (let i = 0; i < data.length; i++){
      if (data[i].id === item.parentId) {
        data[i].children.push({ id: item[rowKey], children: [] });
        break;
      }
      if (data[i].children?.length) {
        setRelationshipTree(data[i].children, item);
      }
    }
    setRelationship(data);
  };

  
   // 重置
  const onReset = () => {
    // 重置搜索框参数
    onResetSearch?.();
 };


  useEffect(() => {
    if (isSerial) {
      setCustomColumns([
        {
          title: intl.formatMessage({
            id: 'columns.title.index',
            defaultMessage: '序号',
          }),
          dataIndex: 'orderIndex',
          render: (_: any, { orderIndex }: any) => (
            <span>{parseInt(orderIndex) > 0 ? parseInt(orderIndex) : ''}</span>
          ),
          key: 'index',
          width: 120,
          fixed: 'left',
          align: 'center',
          search: false,
        },
        ...columns.map((item) => {
          if (!item.title) return item;
          return {
            ...item,
            ellipsis: true,
          };
        }),
      ]);
    } else {
      setCustomColumns(columns);
    }
  }, []);
  useEffect(() => {
    setCustomColumns([
      ...columns.map((item) => {
        if (!item.title) return item;
        return {
          ...item,
        };
      }),
    ]);
  }, [columns]);

  useEffect(() => {
    if (sortType?.id) {
      const data = sortMenu(tableData, sortType.id, sortType.type);
      if (lastTable) {
        markLastItem(data);
      }
      setTableData(data);
    }
  }, [sortType]);

  useEffect(() => {
    // 当依赖值发生变化时执行，刷新表格，保持page和pageSize不变
    tableRef.current.reload();
    // console.log('SearchTable useEffect');
  }, [reload]);

  useEffect(() => {
    if (listItem) {
      if (onExpandType === 'company') {
        addOrDelChildren(listItem, USER_CENTER_COMPANY_MANAGE_LIST, 'parentId');
      } else if (onExpandType === 'dictionaries') {
        addOrDelChildren(listItem, DICTIONARY_CHILDLIST, 'parentId');
      }
    }
  }, [reloadChildren]);

  useEffect(() => {
    if (obj){
      setChildrenFalse(
        obj.idStr,
        obj.items,
        obj.id,
        obj.recordList
      );
    }
  }, [obj]);

  useEffect(() => {
    if (disableEnable?.id) {
      setStatusFalse(tableData, disableEnable.id);
    }
  }, [disableEnable]);
  // useEffect(() => {
  //   console.log(expandedRowKeys);
  //   console.log(relationship);
  // }, [expandedRowKeys]);
  return (
    <div style={{ padding: 24 }}>
      <ProTable<TableListItem>
        locale={{
          emptyText: (
            <Empty
              image={Empty.PRESENTED_IMAGE_SIMPLE}
              description={<span>{intl.formatMessage({ id: 'form.text.noData' })}</span>}
            />
          ),
        }}
        actionRef={tableRef}
        columns={customColumns}
        dataSource={tableData}
        request={getTable}
        scroll={{ x: scrollX || 'max-content' }}
        params={otherParams || {}}
        onDataSourceChange={() => {
          // 清除选中项
          tableRef.current.clearSelected();
        }}
        onReset={onReset}
        rowKey={rowKey || 'id'}
        rowSelection={
          isMass
            ? {
                // 注释该行则默认不显示下拉选项
                selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
                onChange: (selectedRowKeys, value) => {
                  if (setMassIds) {
                    setMassIds(selectedRowKeys as (number|string)[]);
                  }
                  if (selectedValue) {
                    selectedValue(value);
                  }
                },
                getCheckboxProps: getCheckboxProps,
              }
            : undefined
        }
        tableAlertRender={({
          selectedRowKeys,
          // selectedRows,
          // onCleanSelected,
        }:any) => {
          return (
            <Space>
              <FormattedMessage
                id="columns.handel.selected"
                defaultMessage="已选"
              />
              <Typography.Link>{selectedRowKeys.length}</Typography.Link>
              <FormattedMessage id="columns.handel.unit" defaultMessage="项" />
              {/* <a style={{ marginInlineStart: 8 }} onClick={onCleanSelected}>
                  <FormattedMessage id="columns.handel.cancel.selected" defaultMessage="取消选择" />
                </a> */}
            </Space>
          );
        }}
        pagination={{
          hideOnSinglePage: true,
          showQuickJumper: true,
          defaultPageSize: pageSize ? pageSize : 10,
        }}
        search={{
          labelWidth: 'auto',
          // layout: 'vertical',
          // collapsed: true,
        }}
        headerTitle={headerTitle}
        toolbar={toolbar}
        toolBarRender={toolBarRender || undefined}
        expandable={{
          childrenColumnName: expandChildrenColumnName,
          expandedRowRender: expandedRowRender || undefined,
          onExpand: (is: any, item: any) => {
            setRelationshipTree(relationship, item);
            if (setListItem) setListItem(undefined);
            if (onExpandType) expandSwitch(is, item, onExpandType);
            if (
              expandedRowKeys?.filter((str) => str === item[rowKey]).length &&
              item['parentId'] === '0' &&
              setExpandedRowKeys
            ) {
              setExpandedRowKeys([]);
              return;
            }
            if (
              expandedRowKeys?.filter((str) => str === item[rowKey]).length &&
              item['parentId'] !== '0' &&
              setExpandedRowKeys
            ) {
              let list: string[] = [];
              expandedRowKeys?.forEach((record) => {
                if (record !== item[rowKey]) {
                  list.push(record);
                }
              });
              setExpandedRowKeys([...list]);
            } else if (
              expandedRowKeys?.filter((str) => str === item['parentId'])
                .length &&
              item['parentId'] !== '0' &&
              setExpandedRowKeys
            ) {
              setExpandedRowKeys([...expandedRowKeys, item[rowKey]]);
            } else if (setExpandedRowKeys) {
              setExpandedRowKeys([item[rowKey]]);
            }
          },
          expandedRowKeys: expandedRowKeys,
        }}
      />
    </div>
  );
};

export default CompanyTable;
