/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2023-01-04 14:12:31
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2024-09-06 11:13:27
 * @FilePath: /BudgetManaSystem/src/pages/budgetMana/oneBatch/index.tsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */


import BMSPagecontainer from '@/components/BMSPageContainer'
import { BMSTable } from '@/components/BMSTable';
import { getComputeDate } from '@/pages/Home/service';
import { ActionType, ProColumns } from '@ant-design/pro-components';
import { message, Modal, Popover, Table, Tabs, Tooltip } from 'antd';
import { useEffect, useRef, useState } from 'react';
import { caculate, checkRequest, getCheckType, getCurrentCheckStatus, getCurrentZhileiCheckStatus, getData, getZhileiList } from './service';


import './style.less';


import { create, all, number } from 'mathjs'


import * as XLSX from 'xlsx';
import exportTableToMultiExcel from '@/utils/tableToMultiHeaderExcel';
import { getJiezhuanStatus } from '../monthlySet/service';
import { formatMoneyNumber } from '@/utils/format';
import { createFromIconfontCN } from '@ant-design/icons';

const IconFont = createFromIconfontCN({
  scriptUrl: '',
});


const config = {
  number: 'number',
  precision: 14
}
const math = create(all, config as any);


type JsonStructure = {
  code: string;
  name: string;
  expand?: number;
  childTitle?: JsonStructure[];
};

type Column = {
  title: string | JSX.Element;
  dataIndex: string;
  key: string;
  ellipsis: boolean;
  width: number;
  renderText?: any,
  children?: Column[];
};



let checkStatusArr: number[] = []

const OneBatch = () => {


  const [tableColumn, set_tableColumn] = useState<ProColumns[] | any[]>([]);

  const [columnsForExcel, set_columnsForExcel] = useState<ProColumns[] | any[]>([]);

  const [tableData, set_tableData] = useState<any[]>([]);

  const [currentComputeDate, set_currentComputeDate] = useState<string | undefined>();

  const [currentTabKey, set_currentTabKey] = useState('1');

  const [tabs, set_Tabs] = useState<{
    name: any; value: string
  }[]>([]);

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

  const [auditType, set_auditType] = useState('0');

  const [ifShowTip, set_ifShowTip] = useState(false);

  const tableRef = useRef<ActionType>();

  const [tableH, set_tableH] = useState(0);
  const [reportTitle, set_reportTitle] = useState('');
  const [checkType, set_checkType] = useState<string | undefined>(undefined); // 一次分配审核模式，1职类一起审核 2职类分开审核

  const [disAccount, set_disAccount] = useState(false);

  const [ifBanAllAction, set_ifBanAllAction] = useState(true);  //是否掩藏所有操作



  const onTabChange = (activeKey: string) => {
    set_currentTabKey(activeKey);
    set_tableDataFilterParams({
      ...tableDataFilterParams,
      reportCode: activeKey
    });
  }

  const [expandedkeys, set_expandedkeys] = useState<string[]>([]);

  const convertToColumnsFunc = (json: JsonStructure[], ifRender?: boolean, level: number = 1): Column[] => {
    return json.map((item) => {
      let column: Column = {
        title: item.name,
        dataIndex: `key-${item.code}`,
        key: `key-${item.code}`,
        ellipsis: true,
        width: 200,
        renderText(text: any) {
          function formatMoney(num: number) {
            if (typeof num !== 'number' || isNaN(num)) {
              return '-';
            }
            return new Intl.NumberFormat('en-US', { minimumFractionDigits: 0, maximumSignificantDigits: 10 }).format(num);
          }
          return formatMoney(text)
        }
      };

      const isExpanded = expandedkeys.includes(item.code);

      if (item.expand === 1 && item.childTitle && item.childTitle.length > 0) {

        column.title = ifRender ? (
          <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'center', alignContent: 'center' }}>
            <span style={{ display: 'inline-block', maxWidth: '80%', minWidth: 140, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{item.name}</span>
            <div className='expandIcon' onClick={() => {
              if (isExpanded) {
                let _expandedkeys = [...expandedkeys];
                _expandedkeys.splice(expandedkeys.findIndex(a => a == item.code), 1);
                set_expandedkeys([..._expandedkeys]);
              } else {
                set_expandedkeys([...expandedkeys, item.code]);
              }
            }}>
              {isExpanded ? '-' : '+'}
            </div>
          </div>
        ) : item.name;

        if (isExpanded) {
          column.children = convertToColumnsFunc(item.childTitle, ifRender, level + 1);
        }
      }

      return column;
    });
  }


  useEffect(() => {
    tableRef.current?.reload();
  }, [expandedkeys])


  const getTableData = async (params: any, sort: any, filter: any) => {

    const { reportCode = 1 } = params;

    const resp: any = await getData(
      currentComputeDate as string,
      reportCode
    );

    if (resp) {

      const { title, assignmentData, reportName } = resp;
      const columns = convertToColumnsFunc(title, true);
      const columnsForExcel = convertToColumnsFunc(title, false);


      set_tableColumn([
        {
          title: '核算单元代码',
          dataIndex: 'unitCode',
          key: 'unitCode',
          width: 140,
          fixed: 'left',
          ellipsis: true,
          sorter: (a, b) => {
            return b.unitCode.localeCompare(a.unitCode)
          },
        },
        {
          title: '核算单元',
          dataIndex: 'unitName',
          key: 'unitName',
          width: 140,
          fixed: 'left',
          ellipsis: true,
          sorter: (a, b) => {
            return b.unitName.localeCompare(a.unitName)
          },

        },
        ...columns, {
          title: '总奖金',
          dataIndex: 'totalScore',
          key: 'totalScore',
          width: 140,
          fixed: 'right',
          ellipsis: true,
          renderText(text, record, index, action) {
            return formatMoneyNumber(text)
          },

        }]);


      set_columnsForExcel([
        {
          title: '核算单元代码',
          dataIndex: 'unitCode',
          key: 'unitCode',
          width: 140,
          fixed: 'left',
          ellipsis: true,
          sorter: (a, b) => {
            return b.unitCode.localeCompare(a.unitCode)
          },

        },
        {
          title: '核算单元',
          dataIndex: 'unitName',
          key: 'unitName',
          width: 140,
          fixed: 'left',
          ellipsis: true,
          sorter: (a, b) => {
            return b.unitName.localeCompare(a.unitName)
          },
        },
        ...columnsForExcel, {
          title: '总奖金',
          dataIndex: 'totalScore',
          key: 'totalScore',
          width: 140,
          fixed: 'right',
          ellipsis: true,
          renderText(text, record, index, action) {
            return formatMoneyNumber(text)
          },

        }]);

      // set_tableColumn([...mockColumns]);
      // set_columnsForExcel([...mockColumns]);


      const data = assignmentData.map((item: any) => {

        let rowData: { [key: string]: any } = {};

        for (let index = 0; index < item.value.length; index++) {
          for (const key in item.value[index]) {

            if (key != 'code') {
              rowData[`key-${item.value[index].code}`] = item.value[index].value
            }
          }
        }

        return { ...item, ...rowData, id: item.id, columns }
      });

      set_tableData(data);
      set_reportTitle(reportName);

      return {
        data,
        success: true
      }

    }
    return []
  }


  const checkHandle = async (type: string) => {

    if (!checkType) return;

    const resp = await checkRequest({
      computeDate: currentComputeDate as string,
      auditType: type == '0' ? '1' : '0',   //审核类型  1审核 0取消审核
      reportCode: checkType == '2' ? currentTabKey : undefined
    }, checkType);

    if (resp) {
      if (type == '0') {
        message.success('审核提交成功！');
        set_auditType('1');
      }
      if (type == '1') {
        message.success('取消审核提交成功！');
        set_auditType('0');
      }
    }
    return resp;
  }

  const getCurrentComputeDate = async () => {
    const resp = await getComputeDate();
    set_currentComputeDate(resp);
  }

  const getTabList = async () => {
    const resp = await getZhileiList();
    if (resp) {
      set_Tabs(resp.list);
    }
  }


  const confirmCaculateHandle = async () => {
    const resp = await caculate(currentComputeDate as string);
    if (resp) {
      tableRef.current?.reload();
    }
  }


  const getCheckStatus = async (computeDate: string, code?: string) => {

    if (checkType == '1') {
      const resp = await getCurrentCheckStatus(computeDate);
      if (resp) {
        set_auditType('1');  //0 未审核 1 已审核
      } else {
        set_auditType('0');
      }
    }
    if (checkType == '2') {
      const resp = await getCurrentZhileiCheckStatus(computeDate, code ? code : currentTabKey);
      if (resp) {
        set_auditType('1');  //0 未审核 1 已审核
      } else {
        set_auditType('0');
      }
    }

  }

  const generateFunc = () => {

    Modal.confirm({
      title: '注意',
      okText: '确定',
      cancelText: '',
      closable: true,
      content: '计算会覆盖原有数据，确定要继续计算操作？',
      onOk: () => confirmCaculateHandle()
    })
  }

  const exportHandle = async (flag: number) => {
    if (!flag) {
      exportTableToMultiExcel([{ data: tableData, columns: columnsForExcel, sheetName: reportTitle }], `${reportTitle}.xlsx`, true);

    } else {
      const sheetsData = [];
      for (const tab of tabs) {
        const resp: any = await getData(currentComputeDate as string, Number(tab.value));
        if (resp) {
          const { title, assignmentData } = resp;
          const columnsForExcel = convertToColumnsFunc(title, false);
          const columns = [
            {
              title: '核算单元代码',
              dataIndex: 'unitCode',
              key: 'unitCode',
              width: 140,
              fixed: 'left',
              ellipsis: true,
              sorter: (a: { unitCode: any; }, b: { unitCode: string; }) => {
                return b.unitCode.localeCompare(a.unitCode)
              },

            },
            {
              title: '核算单元',
              dataIndex: 'unitName',
              key: 'unitName',
              width: 140,
              fixed: 'left',
              ellipsis: true,
              sorter: (a: { unitName: any; }, b: { unitName: string; }) => {
                return b.unitName.localeCompare(a.unitName)
              },
            },
            ...columnsForExcel, {
              title: '总奖金',
              dataIndex: 'totalScore',
              key: 'totalScore',
              width: 140,
              fixed: 'right',
              ellipsis: true,
              renderText(text: number, record: any, index: any, action: any) {
                return formatMoneyNumber(text)
              },

            }];

          const data = assignmentData.map((item: any) => {
            let rowData: { [key: string]: any } = {};
            for (let index = 0; index < item.value.length; index++) {
              for (const key in item.value[index]) {
                if (key !== 'code') {
                  rowData[`key-${item.value[index].code}`] = item.value[index].value;
                }
              }
            }
            return { ...item, ...rowData, id: item.id, columns };
          });

          sheetsData.push({ data, columns, sheetName: tab.name });
        }
      }

      exportTableToMultiExcel(sheetsData, `一次分配报表数据.xlsx`, true);
    }



  }

  const handleResize = (e: any) => {
    const wH = e.target.innerHeight;
    const tableHeight = wH - 290;
    set_tableH(tableHeight);
  }

  const getCheckTypeHandle = async () => {
    const resp = await getCheckType();
    if (resp && resp.list.length > 0) {
      set_checkType(resp.list[0].value);
    }
  }

  function doResize() {
    setTimeout(() => {
      const ev: any = new Event('resize');
      window.dispatchEvent(ev);
    }, 0)
  }

  useEffect(() => {
    if (tabs.length > 0) {
      set_currentTabKey(tabs[0].value);
    }
  }, [tabs]);

  useEffect(() => {
    if (currentComputeDate && checkType == '2') {
      getCheckStatus(currentComputeDate as string);
    }
  }, [currentTabKey]);


  useEffect(() => {
    if (checkType == '2') {
      checkStatusArr = [];
      tabs.forEach(async (item) => {
        const resp = await getCurrentZhileiCheckStatus(currentComputeDate as string, item.value);

        checkStatusArr.push(resp);

        if (checkStatusArr.length == tabs.length) {
          const total = [...checkStatusArr].reduce((prev, cur) => prev + cur, 0);
          total > 0 ? set_disAccount(true) : set_disAccount(false)
        }

      })
    }
  }, [auditType]);


  const getJiezhuanStatusHandle = async () => {
    const resp = await getJiezhuanStatus(currentComputeDate as string);
    if (resp == 2) {
      set_ifBanAllAction(true);
    } else {
      set_ifBanAllAction(false);
    }
  }


  useEffect(() => {
    if (currentComputeDate && checkType) {
      getCheckStatus(currentComputeDate);
      getJiezhuanStatusHandle();
    }
  }, [currentComputeDate, checkType]);


  useEffect(() => {
    getCurrentComputeDate();
    window.addEventListener('resize', (e) => handleResize(e)) //监听窗口大小改变
    doResize();
    getTabList();
    getCheckTypeHandle();

    return () => {
      window.removeEventListener('resize', (e) => handleResize(e))
    }
  }, [])


  return (
    <BMSPagecontainer className='OneBatch' title={`核算年月：${currentComputeDate}`}>
      <div className='btnGroup'>
        {
          !ifBanAllAction && (
            <Popover open={ifShowTip} content={'当前处于审核中，无法操作！'} >
              <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
                <div className={(auditType == '0' && !disAccount) ? 'caculateBtn' : 'caculateBtn disabled'}
                  onMouseEnter={() => auditType == '0' ? set_ifShowTip(false) : set_ifShowTip(true)}
                  onMouseLeave={() => set_ifShowTip(false)}
                  onClick={() => (auditType == '0' && !disAccount) ? generateFunc() : () => { }}>计算</div>
                <div className={auditType == '0' ? 'caculateBtn' : 'caculateBtn disabled'}
                  style={{ marginRight: 8 }}
                  onMouseEnter={() => auditType == '0' ? set_ifShowTip(false) : set_ifShowTip(true)}
                  onMouseLeave={() => set_ifShowTip(false)}
                  onClick={() => auditType == '0' ? exportHandle(1) : () => { }}>
                  导出全部
                  <Tooltip title="将所有职类的数据导出到一个excel文件并分sheet页放置">
                    <IconFont type="iconshuoming" style={{ fontSize: 16, paddingLeft: 10 }} />
                  </Tooltip>

                </div>
                <div className={auditType == '0' ? 'caculateBtn' : 'caculateBtn disabled'}
                  onMouseEnter={() => auditType == '0' ? set_ifShowTip(false) : set_ifShowTip(true)}
                  onMouseLeave={() => set_ifShowTip(false)}
                  onClick={() => auditType == '0' ? exportHandle(0) : () => { }}>
                  导出当前
                  <Tooltip title={tabs.length>0?`将${(tabs.filter((a)=>a.value == currentTabKey))[0].name}的数据导出到excel文件`:''}>
                  <IconFont type="iconshuoming" style={{ fontSize: 16, paddingLeft: 10 }} />
                  </Tooltip>
                </div>
              </div>
            </Popover>
          )
        }

        {!ifBanAllAction && <div className='checkBtn' onClick={() => checkHandle(`${auditType}`)}>{auditType == '0' ? '审核' : '取消审核'}</div>}
      </div>
      <div className='content'>
        <Tabs
          defaultActiveKey='1'
          onChange={onTabChange}
          items={[
            ...tabs.map(a => ({ label: a.name, key: a.value }))
          ]}
        />
        <div className='tabContent'>
          {currentComputeDate && <BMSTable actionRef={tableRef} rowKey='unitCode' bordered pagination={false} columns={tableColumn as ProColumns[]}
            params={tableDataFilterParams}
            scroll={{ x: 140 * tableColumn.length, y: tableH }}
            request={(params, sort, filter) => getTableData(params, sort, filter)}

            summary={(pageData) => {
              const Caculate = ({ colData }: { colData: any }) => {

                const { dataIndex, children } = colData;

                if (children) {
                  return children.map((child: any, index: number) => (
                    <Caculate key={index} colData={child} />
                  ));
                }

                const total = pageData.reduce((prev, cur) => {
                  //return prev + cur[`${dataIndex}`]
                  if (typeof cur[`${dataIndex}`] == 'number') {
                    return math.add(prev, cur[`${dataIndex}`] as number);
                  }
                }, 0);

                return dataIndex == "unitName" ? <div style={{ textAlign: 'left' }}>合计</div> : (
                  //<span>{typeof total == 'number'?math.format(total, {precision: 14}) : '合计'}</span>
                  <span style={{ textAlign: 'left' }}>{typeof total == 'number' ? Number(total.toFixed(4)) : '-'}</span>
                )
              }

              const renderSummaryRow = (columns: any[]): React.ReactNode[] => {
                return columns.map((colData, index) => {
                  if (colData.children) {
                    return renderSummaryRow(colData.children);
                  } else {
                    return (
                      <Table.Summary.Cell key={index} index={index} align='center' rowSpan={1}>
                        <Caculate colData={colData} />
                      </Table.Summary.Cell>
                    );
                  }
                });
              };

              return (
                <Table.Summary fixed>
                  <Table.Summary.Row>
                    {renderSummaryRow(tableColumn)}
                  </Table.Summary.Row>
                </Table.Summary>
              );
            }}

          />}
        </div>
      </div>

    </BMSPagecontainer>
  )
}

export default OneBatch
