/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2022-12-16 09:42:52
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2023-11-10 10:25:38
 * @FilePath: /BudgetManaSystem/src/pages/budgetMana/monthlySet/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

import { useEffect, useImperativeHandle, useRef, useState } from 'react';
import './style.less';

import { TreeProps, Input, Transfer, Popconfirm, Modal, TransferProps, Table } from 'antd';
import { DataNode } from 'antd/es/tree';

import expandedIcon from '../../../../../public/images/treenode_open.png';
import closeIcon from '../../../../../public/images/treenode_collapse.png';
import type { ColumnsType, TableRowSelection } from 'antd/es/table/interface';

import { createFromIconfontCN } from '@ant-design/icons';
import { addData, delData, editData, getMenuContentType, getMenuRelaActDic, getTableDataRequest, getTreeData, getTreeDataRespType, updateFuncDic } from './service';
import { TransferDirection, TransferItem } from 'antd/es/transfer';

import difference from 'lodash/difference';

import 'dayjs/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';

import React from 'react';
import DirectoryTree from 'antd/es/tree/DirectoryTree';
import { ActionType, ProColumns } from '@ant-design/pro-table';
import KCTable from '@/components/kcTable';
import { getDeepestTreeData } from '@/utils';
import ProForm, { ModalForm, ProFormDependency, ProFormDigit, ProFormInstance, ProFormItem, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from '@ant-design/pro-form';
import { KCInput } from '@/components/KCInput';
import { UserRelaSeletDataListType } from '@/service/user';

const IconFont = createFromIconfontCN({
  scriptUrl: '//at.alicdn.com/t/c/font_1927152_4nm5kxbv4m3.js',
});

const SearchIcon = createFromIconfontCN({
  scriptUrl: '//at.alicdn.com/t/c/font_1927152_g1njmm1kh7b.js',
});

export type TableListItem = {
  key: number;
  name: string;
};

const MonthlyInfoCheck: React.FC = () => {
  const [treeData, set_treeData] = useState<getTreeDataRespType[]>([]);
  const [currentSelectedTreeNode, set_currentSelectedTreeNode] = useState<any | undefined>();

  const [reload, set_reload] = useState(false);

  const [tableDataFilterParams, set_tableDataFilterParams] = useState<any | undefined>();

  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [searchValue, setSearchValue] = useState('');
  const [autoExpandParent, setAutoExpandParent] = useState(true);
  const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState<string>('');

  const [currentOperateRow, set_currentOperateRow] = useState<any | undefined>(undefined); //当前操作的表格行数据

  const [contentType, set_contentType] = useState<any[]>([]); //菜单内容类型列表

  const tableRef = useRef<ActionType>();

  const formRef = useRef<ProFormInstance>();

  const transferTableColumn = [
    {
      title: '功能名称',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: '功能代码',
      dataIndex: 'code',
      key: 'code',
    },
  ];

  const columns: ProColumns[] = [
    {
      title: '名称',
      dataIndex: 'name',
      key: 'name',
      ellipsis: true,
    },
    {
      title: '类型',
      dataIndex: 'contentType',
      key: 'contentType',
      width: 100,
      render: (_: any, record: any) => {
        //console.log({ record });
        switch (record.type) {
          case 0:
            return '目录';
          case 1:
            return '菜单';
          case 2:
            return 'api';
          case 3:
            return '系统';
          case 4:
            return '有数bi';
          case 5:
            return '体系';
          case 6:
            return '中心层';
          case 7:
            return '平台层';
          default:
            break;
        }
      },
    },
    {
      title: 'Path',
      width: 300,
      dataIndex: 'path',
      key: 'path',
      ellipsis: true,
    },
    {
      title: '内容',
      dataIndex: 'contentType',
      key: 'contentType',
      width: 100,
      valueEnum: {
        0: '一般',
        1: '报告',
        2: '大屏',
        3: '填报',
        4: '空白',
        5: '静态',
        6: '外部系统嵌入',
      },
    },
    {
      title: '功能',
      dataIndex: 'deptName',
      key: 'deptName',
      render: (_: any, record: any) => {
        if (record.functionList) {
          return record.functionList.reduce((prev: any, cur: any) => {
            return `${prev ? prev + ' | ' : prev}${cur.name}`;
          }, '');
        }
        return '-';
      },
    },
    {
      title: '操作',
      key: 'option',
      width: 120,
      fixed: 'right',
      valueType: 'option',
      render: (_: any, record: any) => {
        return record.type != 1 && record.type != 2 && record.type != 4
          ? [
              <UpDataActBtn key={'add'} record={record} type="ADD" />,
              <UpDataActBtn key={'act'} record={record} type="EDIT" />,
              <Popconfirm title="是否确认删除？" key="del" onConfirm={() => delMenuHandle(record)}>
                <a>删除</a>
              </Popconfirm>,
            ]
          : [
              <a key={'fuc'} onClick={() => addFuncHandle(record)}>
                功能
              </a>,
              <UpDataActBtn key={'act'} record={record} type="EDIT" />,
              <Popconfirm title="是否确认删除？" key="del" onConfirm={() => delMenuHandle(record)}>
                <a>删除</a>
              </Popconfirm>,
            ];
      },
    },
  ];

  const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => {
    //console.log('selected', selectedKeys, info);
    const { node } = info;
    set_currentSelectedTreeNode(node);
  };

  const getContentType = async () => {
    const currentSelectedTab = localStorage.getItem('currentSelectedTab');
    const { systemId } = JSON.parse(currentSelectedTab as string);
    const resp = await getMenuContentType(systemId);
    if (resp) {
      set_contentType(resp.list);
    }
  };

  const getTableData = async (params: any, sort: any, filter: any) => {
    set_reload(false);
    if (currentSelectedTreeNode) {
      const resp = await getTableDataRequest(params);
      if (resp) {
        return {
          data: resp,
          success: true,
        };
      }
      return {
        data: [],
        success: true,
      };
    }

    return [];
  };

  const addFuncHandle = (record: any) => {
    set_currentOperateRow(record);
    const ref = React.createRef<{ save: any }>();

    Modal.confirm({
      title: '菜单功能设置（核算单元管理）',
      icon: '',
      width: 672,
      okText: '确定',
      cancelText: '取消',
      content: <TableTransfer ref={ref} record={record} leftColumns={transferTableColumn} rightColumns={transferTableColumn} dataSource={[]}></TableTransfer>,
      onOk: () => {
        return ref.current && ref.current.save();
      },
    });
  };

  const delMenuHandle = async (record: any) => {
    const resp = await delData(record.menuId);
    resp && set_reload(true);
  };

  interface DataType {
    key: string;
    title: string;
    description: string;
    disabled: boolean;
    tag: string;
  }

  interface TableTransferProps extends TransferProps<TransferItem> {
    dataSource: DataType[];
    leftColumns: ColumnsType<DataType>;
    rightColumns: ColumnsType<DataType>;
    record: any;
  }

  const TableTransfer = React.forwardRef(({ leftColumns, rightColumns, record, ...restProps }: TableTransferProps, ref) => {
    const [_data, _set_data] = useState<any>();
    const [targetKeys, setTargetKeys] = useState<string[]>([]);
    const [datasource, set_datasource] = useState<any[]>([]);
    const [selectedKeys, setSelectedKeys] = useState<string[]>([]);

    //获取页面权限字典
    const getFuncList = async () => {
      const resp = await getMenuRelaActDic();
      if (resp) {
        set_datasource(resp);

        if (record && record.functionList) {
          const defaultSelctedkeys = record.functionList.map((item: any) => item.code);

          setTargetKeys(defaultSelctedkeys);
        }
      }
    };

    const onChange = (nextTargetKeys: string[]) => {
      setTargetKeys(nextTargetKeys);
    };

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

    useImperativeHandle(ref, () => ({
      save: async () => {
        const data = datasource.filter((item) => targetKeys.includes(item.code));

        const resp = await updateFuncDic({
          menuId: record.menuId,
          function: data,
        });
        if (resp) {
          set_reload(true);
        }
      },
    }));

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

    return (
      <Transfer
        className="TableTransfer"
        showSearch
        titles={['待选项目', '已选项目']}
        locale={{
          itemUnit: '项',
          itemsUnit: '项',
          searchPlaceholder: '请输入',
        }}
        onChange={onChange}
        onSelectChange={onSelectChange}
        dataSource={datasource}
        rowKey={(record) => record.code}
        targetKeys={targetKeys}
        selectedKeys={selectedKeys}
        filterOption={(inputValue, item) => {
          return item.name!.indexOf(inputValue) !== -1;
        }}
      >
        {({ direction, filteredItems, onItemSelectAll, onItemSelect, selectedKeys: listSelectedKeys, disabled: listDisabled }) => {
          // console.log({ filteredItems, listSelectedKeys,direction });
          const columns = direction === 'left' ? leftColumns : rightColumns;

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

          return (
            <Table
              rowSelection={rowSelection}
              columns={columns as TransferItem[]}
              dataSource={filteredItems}
              size="small"
              rowKey={'code'}
              style={{ pointerEvents: listDisabled ? 'none' : undefined }}
              onRow={({ code, disabled: itemDisabled }) => ({
                onClick: () => {
                  if (itemDisabled || listDisabled) return;
                  onItemSelect(code as string, !listSelectedKeys.includes(code as string));
                },
              })}
            />
          );
        }}
      </Transfer>
    );
  });

  const dataList: any[] = [];

  const getParentKey = (key: React.Key, tree: any[]): React.Key => {
    let parentKey: React.Key;
    for (let i = 0; i < tree.length; i++) {
      const node = tree[i];
      if (node.children) {
        if (node.children.some((item: { code: React.Key }) => item.code === key)) {
          parentKey = node.code;
        } else if (getParentKey(key, node.children)) {
          parentKey = getParentKey(key, node.children);
        }
      }
    }
    return parentKey!;
  };

  const onTreeSearchKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target;
    const newExpandedKeys = dataList.map((item) => {
      if (item.name.indexOf(value) > -1) {
        return getParentKey(item.code, treeData);
      }
      return null;
    });

    const b = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i);

    setExpandedKeys(newExpandedKeys as React.Key[]);
    setSearchValue(value);
    setAutoExpandParent(true);
  };

  const onExpand = (newExpandedKeys: React.Key[]) => {
    setExpandedKeys(newExpandedKeys);
    setAutoExpandParent(false);
  };

  const generateList = (data: getTreeDataRespType[]) => {
    for (let i = 0; i < data.length; i++) {
      const node = data[i];
      const { code, name } = node;
      dataList.push({ code, name: name });
      if (node.children) {
        generateList(node.children);
      }
    }
  };
  generateList(treeData as any);

  const getTreeReqFunc = async (name?: string) => {
    const resp = await getTreeData();
    set_treeData(resp);
  };

  const tableDataSearchHandle = (paramName: string) => {
    set_tableDataFilterParams({
      ...tableDataFilterParams,
      [`${paramName}`]: tableDataSearchKeywords,
    });
  };

  const updateTable = async (type: 'EDIT' | 'ADD', formVal: any, record: any) => {
    if (type == 'ADD') {
      let data = undefined;
      if (record) {
        //添加操作
        data = { ...formVal, parentId: record.menuId, systemId: record.systemId };
      } else {
        //新增
        data = { ...formVal, parentId: currentSelectedTreeNode.code, systemId: currentSelectedTreeNode.code };
      }

      const resp = await addData({ ...data });

      if (resp) {
        set_reload(true);
      }
    }
    if (type == 'EDIT') {
      const resp = await editData({ ...record, ...formVal });
      if (resp) {
        set_reload(true);
      }
    }

    set_currentOperateRow(undefined);

    return true;
  };

  const UpDataActBtn = ({ record, type }: { record: any; type: 'EDIT' | 'ADD' }) => {
    return (
      <ModalForm
        className="systemNavManaForm"
        title={`${type == 'EDIT' ? '编辑' : '新增'}菜单`}
        width={688}
        initialValues={type == 'EDIT' ? { ...record } : { isHomepage: 0 }}
        trigger={type == 'EDIT' ? <a key="edit">编辑</a> : record ? <a className="add">添加</a> : <span>新增</span>}
        formRef={formRef}
        grid={true}
        onFinish={(val) => {
          set_currentOperateRow(record);
          return updateTable(type, val, record);
        }}
      >
        <ProFormText name="name" label="名称：" placeholder="请输入" colProps={{ span: 12 }} rules={[{ required: true, message: '名称不能为空!' }]} />
        <ProFormSelect
          name="type"
          label="类型："
          placeholder="请输入"
          colProps={{ span: 12 }}
          options={[
            {
              label: '目录',
              value: 0,
            },
            {
              label: '菜单',
              value: 1,
            },
          ]}
          rules={[{ required: true, message: '类型不能为空!' }]}
        />
        <ProFormText name="path" label="Path：" placeholder="请输入" colProps={{ span: 12 }} rules={[{ required: true, message: 'Path不能为空!' }]} />
        <ProFormText
          name="icon"
          label="icon："
          placeholder="请输入"
          colProps={{ span: 12 }}
          //rules={[{ required: true, message: '类型代码不能为空!' }]}
        />
        <ProFormDigit
          name="orderNum"
          label="顺序号："
          width={'xs'}
          placeholder="请输入"
          colProps={{ span: 12 }}
          //rules={[{ required: true, message: '类型代码不能为空!' }]}
        />
        <ProFormDependency name={['type']}>
          {({ type }) =>
            type == 1 && (
              <ProFormRadio.Group
                name="isHomepage"
                label="是否首页："
                width={'xs'}
                placeholder="请选择"
                colProps={{ span: 12 }}
                rules={[{ required: true, message: '是否为首页不能为空!' }]}
                options={[
                  {
                    label: '是',
                    value: 1,
                  },
                  {
                    label: '否',
                    value: 0,
                  },
                ]}
                //rules={[{ required: true, message: '类型代码不能为空!' }]}
              />
            )
          }
        </ProFormDependency>

        <ProFormDependency name={['type']}>
          {({ type }) =>
            type == 1 && (
              <ProForm.Group colProps={{ span: 12 }} align="start">
                <ProFormSelect
                  name="contentType"
                  label="内容类型："
                  placeholder="请输入"
                  width={100}
                  colProps={{ span: 8 }}
                  request={async () => {
                    if (contentType) {
                      return contentType.map((a: any) => ({ label: a.name, value: Number(a.code) }));
                    }
                    return [];
                  }}
                  fieldProps={{
                    onChange(value, option) {
                      if (value == 1) {
                        //报告页面
                        const need = contentType.filter((item: any) => item.code == `${value}`);
                        if (need.length > 0) formRef.current?.setFieldValue('url', need[0].value);
                      }
                    },
                  }}
                  // options={[
                  //     { label: '一般', value: 0 },
                  //     { label: '报告', value: 1 },
                  //     { label: '大屏', value: 2 },
                  //     { label: '填报', value: 3 },
                  //     { label: '空白', value: 4 },
                  //     { label: '静态', value: 5 },
                  // ]}
                  rules={[{ required: true, message: '类型不能为空!' }]}
                />
                <ProFormDependency name={['contentType']}>
                  {({ contentType }) => {
                    return (
                      contentType == 1 && (
                        <div style={{ position: 'relative', top: 24 }}>
                          <ProFormText
                            noStyle
                            width={210}
                            className="reportId"
                            name="reportId"
                            placeholder="请输入报告Id"
                            colProps={{ span: 16 }}
                            //rules={[{ required: true, message: '类型代码不能为空!' }]}
                          />
                        </div>
                      )
                    );
                  }}
                </ProFormDependency>
              </ProForm.Group>
            )
          }
        </ProFormDependency>

        <ProFormDependency name={['type']}>
          {({ type }) =>
            type == 1 && (
              <ProFormText
                name="url"
                label="URL："
                placeholder="请输入"
                colProps={{ span: 12 }}
                //rules={[{ required: true, message: '类型代码不能为空!' }]}
              />
            )
          }
        </ProFormDependency>

        <ProFormTextArea name="description" label="描述：" placeholder="请输入" colProps={{ span: 24 }} />
      </ModalForm>
    );
  };

  useEffect(() => {
    if (currentSelectedTreeNode) {
      set_tableDataFilterParams({ ...tableDataFilterParams, systemId: currentSelectedTreeNode.code });
    }
  }, [currentSelectedTreeNode]);

  useEffect(() => {
    //初始化左侧树结构数据后

    if (treeData?.length > 0) {
      if (treeData[0].children && treeData[0].children.length > 0) {
        const [node, nodeParent] = getDeepestTreeData(treeData[0], 'children');

        set_currentSelectedTreeNode(node);
        setExpandedKeys([nodeParent.code]);
      }
    }
  }, [treeData]);

  useEffect(() => {
    getTreeReqFunc();
    getContentType();
  }, []);

  return (
    <div className="SystemNavMana">
      <div className="leftTree">
        <div className="search">
          <Input className="searchInput" placeholder="请输入" size="small" allowClear style={{ marginBottom: 16 }} onChange={onTreeSearchKeyChange} suffix={<SearchIcon type="iconsousuo" />} />
        </div>
        {treeData && treeData.length > 0 && (
          <DirectoryTree
            fieldNames={{ title: 'name', key: 'code' }}
            rootStyle={{ overflowY: 'scroll', overflowX: 'hidden' }}
            onSelect={onSelect}
            onExpand={onExpand}
            expandedKeys={expandedKeys}
            autoExpandParent={autoExpandParent}
            selectedKeys={currentSelectedTreeNode ? [currentSelectedTreeNode.code] : []}
            blockNode={true}
            icon={() => null}
            titleRender={(nodeData: any) => {
              const strTitle = nodeData.name as string;
              const index = strTitle.indexOf(searchValue);
              const beforeStr = strTitle.substring(0, index);
              const afterStr = strTitle.slice(index + searchValue.length);
              const title =
                index > -1 ? (
                  <span>
                    {beforeStr}
                    <span className="site-tree-search-value" style={{ color: 'red', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {searchValue}
                    </span>
                    {afterStr}
                  </span>
                ) : (
                  <span className="strTitle">{strTitle}</span>
                );
              return (
                <div
                  style={{
                    display: 'flex',
                    flexDirection: 'row',
                    width: '100%',
                    justifyContent: 'flex-start',
                    alignItems: 'center',
                    height: 32,
                    borderRadius: '4px',
                    overflow: 'hidden',
                    color: '#17181A',
                    textOverflow: 'ellipsis',
                    whiteSpace: 'nowrap',
                  }}
                >
                  {title}
                </div>
              );
            }}
            defaultSelectedKeys={[treeData[0].children[0].code]}
            treeData={treeData as unknown as DataNode[]}
            // treeData={treeDataNew}
            switcherIcon={(props: any) => {
              const { expanded } = props;
              //return <button className='site-table-row-expand-icon site-table-row-expand-icon-expanded'></button>
              return !expanded ? (
                <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={expandedIcon} />
              ) : (
                <img style={{ width: 20, height: 20, position: 'relative', top: 5 }} src={closeIcon} />
              );
            }}
          />
        )}
      </div>
      {/* <div style={{width:16,height:'92vh',background:'#F5F7FA'}}></div> */}
      <div className="rightContent">
        <div className="tableToolbar">
          <div className="filter">
            <div className="filterItem">
              <span className="label">检索：</span>
              <KCInput
                placeholder={'请输入菜单名称'}
                style={{ width: 160 }}
                search
                allowClear
                onChange={(e) => {
                  set_tableDataSearchKeywords(e.target.value);
                  if (e.target.value.length == 0) {
                    set_tableDataFilterParams({
                      ...tableDataFilterParams,
                      name: '',
                    });
                  }
                }}
                onSearch={() => tableDataSearchHandle('name')}
              />
            </div>
          </div>

          <div className={'btnGroup'}>
            <UpDataActBtn key={'act'} record={undefined} type="ADD" />
          </div>
        </div>
        {currentSelectedTreeNode && (
          <KCTable
            pagination={false}
            reload={reload}
            newVer
            params={tableDataFilterParams}
            rowKey="menuId"
            columns={columns as ProColumns[]}
            request={(params: any, sort: any, filter: any) => getTableData(params, sort, filter)}
          />
        )}
      </div>
    </div>
  );
};

export default MonthlyInfoCheck;
