import React, { Key, useEffect, useImperativeHandle, useState } from 'react';
import { Transfer } from 'antd';
import { TransferItem, TransferProps } from 'antd/es/transfer';
import { ColumnsType } from 'antd/es/table';
import { difference } from 'lodash';
import { TableRowSelection } from 'antd/es/table/interface';
import { KCIMTable } from '@/components/KCIMTable';
import { ProColumns } from '@ant-design/pro-components';
import { Tabs, Tree } from 'antd';

import { log } from 'mathjs';
import { getAccountingSubjectList } from '../../accountingAccountSet/accountingSubMana/service';
import { getApportionmentLevelList } from '../../costAllocationSet/allocationLevelSet/service';
import { getResponsibilityCenterList } from '../../responsibilityCenterSet/responsibilityCenter/service';
import {
  findAllParents,
  renameChildListToChildren,
  searchLeaves,
} from '@/utils/tooljs';
import { getHasSetReportRelation } from './service';

interface TableTransferProps extends TransferProps<TransferItem> {
  leftColumns: ProColumns[];
  rightColumns: ProColumns[];
  record: any;
  settingType: number;
  keyName: string;
  onSave: (
    selectedKeys: Key[],
    selectedRowKeys: any[],
    settingType: number,
  ) => void;
}

const flattenTreeData = (
  treeData: any[],
  childKey = 'children',
  parentKey = 'parentId',
) => {
  let result: any[] = [];

  function flatten(node: any, parentId = null) {
    // 创建一个新对象，包含原始节点的所有属性，除了 children，并添加 parentId
    const { [childKey]: _, ...flatNode } = node;
    result.push({ ...flatNode, [parentKey]: parentId });

    // 如果节点有子节点，递归扁平化这些子节点
    if (node[childKey] && node[childKey].length > 0) {
      node[childKey].forEach((childNode: any) => flatten(childNode, node.id));
    }
  }

  // 遍历每个根级节点
  treeData.forEach((node) => flatten(node));

  return result;
};

function buildTree(
  flatData: any[],
  rootParentId = null,
  idKey = 'id',
  parentKey = 'parentId',
  childrenKey = 'children',
) {
  const nodeMap = new Map();

  // 首先，将所有节点存储到一个 Map 中，以便快速访问
  flatData.forEach((node) => nodeMap.set(node[idKey], { ...node }));

  const tree: any[] = [];

  flatData.forEach((node) => {
    const parentNode = nodeMap.get(node[parentKey]);

    if (parentNode) {
      // 检查父节点是否已经有了 children 属性
      if (!parentNode[childrenKey]) {
        parentNode[childrenKey] = [];
      }
      // 将当前节点添加到父节点的 children 数组中
      parentNode[childrenKey].push(nodeMap.get(node[idKey]));
    } else if (node[parentKey] === rootParentId) {
      // 如果没有父节点且 parentId 与根 parentId 匹配，则为根节点
      tree.push(nodeMap.get(node[idKey]));
    } else {
      tree.push(nodeMap.get(node[idKey]));
    }
  });

  // 清除那些 children 长度为 0 的节点的 children 属性
  function clearEmptyChildren(node: any) {
    if (node[childrenKey] && node[childrenKey].length === 0) {
      delete node[childrenKey];
    } else if (node[childrenKey]) {
      node[childrenKey].forEach(clearEmptyChildren);
    }
  }

  tree.forEach(clearEmptyChildren);

  return tree;
}

const TableTransfer = React.forwardRef(
  (
    {
      leftColumns,
      rightColumns,
      keyName,
      record,
      settingType,
      onSave,
      ...restProps
    }: TableTransferProps,
    ref,
  ) => {
    const [_data, _set_data] = useState<any>();
    const [targetKeys, setTargetKeys] = useState<string[]>(
      record.accountingIds
        ? [...record.accountingIds.map((a: string) => Number(a))]
        : [],
    );
    const [datasource, set_datasource] = useState<any[]>([]);
    const [selectedKeys, setSelectedKeys] = useState<string[]>(
      record.accountingIds
        ? [...record.accountingIds.map((a: string) => Number(a))]
        : [],
    );
    const [accountType, set_accountType] = useState(1);
    const [tabs, set_tabs] = useState<any[]>([]);

    //获取列表
    const getFuncList = async () => {
      if (settingType == 1) {
        const resp = await getAccountingSubjectList({
          pageSize: 500,
          current: 1,
          accountType,
        });
        if (resp) {
          const initData = await getHasSetReportRelation({
            reportId: record.id,
            relation: settingType,
          });
          if (initData) {
            const hasSelectedKeys = initData.map((a: any) => a.code);

            const hasSelectedRows = flattenTreeData(resp.list).filter(
              (a: any) => hasSelectedKeys.includes(a.accountingCode),
            );
            const selectedKeys = hasSelectedRows.map((a: any) => a.id);
            // setSelectedKeys(selectedKeys);
            setTargetKeys(selectedKeys);
          }
          set_datasource(resp.list);
          _set_data(resp.list);
        }
      }
      if (settingType == 2) {
        const resp = await getApportionmentLevelList({
          pageSize: 500,
          current: 1,
        });
        if (resp) {
          const initData = await getHasSetReportRelation({
            reportId: record.id,
            relation: settingType,
          });
          if (initData) {
            const hasSelectedKeys = initData.map((a: any) => Number(a.id));
            const hasSelectedRows = resp.list.filter((a: any) =>
              hasSelectedKeys.includes(a.id),
            );
            const selectedKeys = hasSelectedRows.map((a: any) => a.id);
            // setSelectedKeys(selectedKeys);
            setTargetKeys(selectedKeys);
          }
          set_datasource(resp.list);
          _set_data(resp.list);
        }
      }
      if (settingType == 3) {
        const resp = await getResponsibilityCenterList({
          pageSize: 500,
          current: 1,
        });
        //const opendedArr = renameChildListToChildren(resp.list, 'child');
        if (resp) {
          const initData = await getHasSetReportRelation({
            reportId: record.id,
            relation: settingType,
          });
          if (initData) {
            const hasSelectedKeys = initData.map((a: any) => a.code);
            const hasSelectedRows = resp.list.filter((a: any) =>
              hasSelectedKeys.includes(a.responsibilityCode),
            );
            const selectedKeys = hasSelectedRows.map((a: any) => a.id);
            // setSelectedKeys(selectedKeys);
            setTargetKeys(selectedKeys);
          }
          set_datasource(renameChildListToChildren(resp.list, 'child'));
          _set_data(renameChildListToChildren(resp.list, 'child'));
        }
      }
    };

    const onChange = (nextTargetKeys: string[]) => {
      // console.log({ nextTargetKeys });
      setTargetKeys(nextTargetKeys);
    };

    const onSelectChange = (
      sourceSelectedKeys: string[],
      targetSelectedKeys: string[],
    ) => {
      // console.log('sourceSelectedKeys:', sourceSelectedKeys, 'targetSelectedKeys:', targetSelectedKeys);
      setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
    };

    useImperativeHandle(ref, () => ({
      save: async () => {
        if (settingType == 1 || settingType == 3) {
          const items = flattenTreeData(datasource).filter((a) =>
            targetKeys.includes(a[`${keyName}`]),
          );
          onSave(targetKeys, items, settingType);
        } else {
          const items = datasource.filter((a) =>
            targetKeys.includes(a[`${keyName}`]),
          );
          onSave(targetKeys, items, settingType);
        }
      },
    }));

    const onTabChanged = (key: string) => {
      set_accountType(Number(key));
    };

    useEffect(() => {
      getFuncList();
    }, [accountType]);

    useEffect(() => {
      set_tabs([
        {
          label: '收入',
          key: 1,
        },
        {
          label: '支出',
          key: 2,
        },
      ]);
    }, []);

    return (
      <div>
        {settingType == 1 && (
          <Tabs
            defaultActiveKey={tabs.length > 0 ? tabs[0].key : undefined}
            items={tabs}
            key={'key'}
            onChange={(key) => onTabChanged(key)}
          />
        )}
        <Transfer
          className="TableTransfer"
          showSearch
          titles={['待选项', '已选项']}
          locale={{
            itemUnit: '项',
            itemsUnit: '项',
            searchPlaceholder: '请输入',
          }}
          oneWay={false}
          onChange={onChange}
          onSelectChange={onSelectChange}
          dataSource={
            settingType == 2 ? datasource : flattenTreeData(datasource)
          }
          rowKey={(record) => record[`${keyName}`]}
          targetKeys={targetKeys}
          selectedKeys={selectedKeys}
          filterOption={(inputValue, item) => {
            if (settingType == 1) {
              return item['accountingName']!.indexOf(inputValue) !== -1;
            }
            if (settingType == 2) {
              return item['shareName']!.indexOf(inputValue) !== -1;
            }
            if (settingType == 3) {
              return item['responsibilityName']!.indexOf(inputValue) !== -1;
            }
            return false;
          }}
        >
          {({
            direction,
            filteredItems,
            onItemSelectAll,
            onItemSelect,
            selectedKeys: listSelectedKeys,
            disabled: listDisabled,
          }) => {
            const columns = direction === 'left' ? leftColumns : rightColumns;

            const rowSelection: TableRowSelection<TransferItem> = {
              getCheckboxProps: (item) => ({
                disabled: listDisabled || item.disabled,
              }),
              onSelectAll(selected, selectedRows) {
                const treeSelectedKeys = selectedRows.map(
                  (a) => a[`${keyName}`],
                );
                const diffKeys = selected
                  ? difference(treeSelectedKeys, listSelectedKeys)
                  : difference(listSelectedKeys, treeSelectedKeys);
                onItemSelectAll(diffKeys as string[], selected);
              },
              onSelect(item, selected) {
                onItemSelect(item[`${keyName}`], selected);
              },
              selectedRowKeys: listSelectedKeys,
            };

            return (
              <KCIMTable
                rowSelection={rowSelection}
                columns={columns as TransferItem[]}
                dataSource={
                  settingType == 2
                    ? filteredItems
                    : direction == 'left'
                    ? buildTree(filteredItems)
                    : filteredItems
                }
                size="small"
                bordered={false}
                rowKey={keyName}
                scroll={{ y: `calc(100vh - )` }}
                pagination={{
                  showTitle: false,
                  pageSize: 9,
                  showLessItems: false,
                  simple: true,
                  showTotal: () => false,
                }}
                tableAlertRender={false}
                style={{ pointerEvents: listDisabled ? 'none' : undefined }}
                onRow={(row) => ({
                  onClick: () => {
                    if (row.itemDisabled || listDisabled) return;
                    onItemSelect(
                      row[`${keyName}`],
                      !listSelectedKeys.includes(row[`${keyName}`]),
                    );
                  },
                })}
              />
            );
          }}
        </Transfer>
      </div>
    );
  },
);

export default TableTransfer;
