/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2025-01-20 10:00:00
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2025-08-01 15:13:42
 * @FilePath: /CostAccountingSys/src/pages/hospitalProfitAndLoss/index.tsx
 * @Description: 全院损益报表查询界面
 */

import KCIMPagecontainer from '@/components/KCIMPageContainer';
import { KCIMTable } from '@/components/KCIMTable';
import { createFromIconfontCN } from '@ant-design/icons';
import { ActionType } from '@ant-design/pro-components';
import { ProColumns } from '@ant-design/pro-table';
import { message, Tabs, Input, DatePicker, Alert } from 'antd';
import { Key, useEffect, useRef, useState } from 'react';
import * as XLSX from 'xlsx-js-style';
import moment from 'moment';
import 'moment/locale/zh-cn';
import locale from 'antd/es/date-picker/locale/zh_CN';
import { getBatchHospProfitList } from './service';
import './style.less';
import React from 'react';
import { getDicDataBySysId, getParamsDataBySysId } from '@/services/getDic';
import { formatMoneyNumber } from '@/utils/format';
import { useModel } from '@umijs/max';
import { useLocation } from '@umijs/max';

const { RangePicker } = DatePicker;

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

const DEFAULT_FONT_COLOR = 'rgba(0, 0, 0, 0.85)';

const normalizeColor = (rawColor: any) => {
  if (typeof rawColor !== 'string') return DEFAULT_FONT_COLOR;
  const color = rawColor.trim();
  if (!color) return DEFAULT_FONT_COLOR;
  return color;
};

const getReportFontColor = (record: any) =>
  normalizeColor(
    record?.fontColor ||
      record?.fontcolor ||
      record?.font_color ||
      DEFAULT_FONT_COLOR,
  );

const toHex2 = (num: number) =>
  Math.max(0, Math.min(255, Math.round(num)))
    .toString(16)
    .padStart(2, '0')
    .toUpperCase();

const convertToExcelArgb = (rawColor: any) => {
  const color = normalizeColor(rawColor);
  const hexColorMatch = color.match(
    /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/,
  );
  if (hexColorMatch) {
    const hex = hexColorMatch[1];
    if (hex.length === 3) {
      const r = hex[0] + hex[0];
      const g = hex[1] + hex[1];
      const b = hex[2] + hex[2];
      return `FF${(r + g + b).toUpperCase()}`;
    }
    if (hex.length === 6) {
      return `FF${hex.toUpperCase()}`;
    }
    // CSS 的 #RRGGBBAA 转成 Excel 需要的 AARRGGBB
    const rrggbb = hex.slice(0, 6).toUpperCase();
    const aa = hex.slice(6, 8).toUpperCase();
    return `${aa}${rrggbb}`;
  }

  const rgbaMatch = color.match(
    /^rgba?\(\s*([0-9.]+)\s*,\s*([0-9.]+)\s*,\s*([0-9.]+)\s*(?:,\s*([0-9.]+)\s*)?\)$/i,
  );
  if (rgbaMatch) {
    const r = Number(rgbaMatch[1]);
    const g = Number(rgbaMatch[2]);
    const b = Number(rgbaMatch[3]);
    const alphaRaw = rgbaMatch[4];
    const alpha =
      alphaRaw === undefined ? 1 : Math.max(0, Math.min(1, Number(alphaRaw)));
    return `${toHex2(alpha * 255)}${toHex2(r)}${toHex2(g)}${toHex2(b)}`;
  }

  return 'FF000000';
};

// 数据转换函数
const transformData = (data: any[]) => {
  const resultMap: Map<
    string,
    { reportName: string; key: string; children?: any[]; [key: string]: any }
  > = new Map();

  // 转换单个条目
  const transformEntry = (
    entry: any,
    computeDate: string,
    allowDrillDown?: boolean,
    isMonthlyAccumulation?: boolean,
    isAuditMonth?: boolean,
  ) => {
    if (!entry) return {};
    const transformedEntry = { ...entry };

    // 添加标志字段到每个节点
    if (allowDrillDown !== undefined) {
      transformedEntry.allowDrillDown = allowDrillDown;
    }
    if (isMonthlyAccumulation !== undefined) {
      transformedEntry.isMonthlyAccumulation = isMonthlyAccumulation;
    }
    if (isAuditMonth !== undefined) {
      transformedEntry.isAuditMonth = isAuditMonth;
    }

    // 根据 dataType 处理不同类型的数据
    const formatValue = (value: number) => {
      if (value == null) return null;

      if (entry.dataType === 2) {
        // 百分比类型
        return `${(value * 100).toFixed(entry.decimalPlace || 2)}%`;
      } else {
        // 数值类型 (dataType === 1 或未定义)
        return formatMoneyNumber(value, {
          decimalPlaces: entry.decimalPlace,
          useThousandSeparator: Boolean(entry.permil),
        });
      }
    };

    // 处理各个字段
    transformedEntry[`${computeDate}_amount`] = formatValue(entry.amount);
    transformedEntry[`${computeDate}_budgetAmount`] = formatValue(
      entry.budgetAmount,
    );
    transformedEntry[`${computeDate}_prevPeriodAmount`] = formatValue(
      entry.prevPeriodAmount,
    );
    transformedEntry[`${computeDate}_samePeriodAmount`] = formatValue(
      entry.samePeriodAmount,
    );

    // 百分比字段始终显示为百分比
    transformedEntry[`${computeDate}_completionRate`] =
      entry.completionRate != null
        ? `${(entry.completionRate * 100).toFixed(entry.decimalPlace || 2)}%`
        : null;
    transformedEntry[`${computeDate}_momRate`] =
      entry.momRate != null
        ? `${(entry.momRate * 100).toFixed(entry.decimalPlace || 2)}%`
        : null;
    transformedEntry[`${computeDate}_yoyRate`] =
      entry.yoyRate != null
        ? `${(entry.yoyRate * 100).toFixed(entry.decimalPlace || 2)}%`
        : null;

    return transformedEntry;
  };

  // 合并新的条目到现有条目，不覆盖已有的字段
  const mergeEntries = (existingEntry: any, newEntry: any) => {
    for (const key in newEntry) {
      if (
        !existingEntry[key] ||
        key.endsWith('_amount') ||
        key.endsWith('_percent')
      ) {
        existingEntry[key] = newEntry[key];
      }
    }
  };

  // 递归处理每个节点及其子节点
  const processNode = (
    node: any,
    computeDate: string,
    allowDrillDown?: boolean,
    isMonthlyAccumulation?: boolean,
    isAuditMonth?: boolean,
  ): any => {
    if (!node) return {};

    const transformedNode = transformEntry(
      node,
      computeDate,
      allowDrillDown,
      isMonthlyAccumulation,
      isAuditMonth,
    );

    if (node.children && Array.isArray(node.children)) {
      const processedChildren = node.children.map((child: any) =>
        processNode(
          child,
          computeDate,
          allowDrillDown,
          isMonthlyAccumulation,
          isAuditMonth,
        ),
      );
      transformedNode.children = mergeChildren(
        transformedNode.children || [],
        processedChildren,
      );
    }

    return transformedNode;
  };

  // 合并子节点，确保同一个父节点下的子节点是唯一的
  const mergeChildren = (existingChildren: any[], newChildren: any[]) => {
    newChildren.forEach((newChild) => {
      const existingChild = existingChildren.find(
        (child) =>
          child.reportName === newChild.reportName &&
          child.key === newChild.key,
      );

      if (existingChild) {
        mergeEntries(existingChild, newChild);
        if (newChild.children && Array.isArray(newChild.children)) {
          existingChild.children = mergeChildren(
            existingChild.children || [],
            newChild.children,
          );
        }
      } else {
        existingChildren.push(newChild);
      }
    });

    return existingChildren;
  };

  // 主处理逻辑
  data.forEach((item) => {
    const {
      computeDate,
      profitVoList,
      allowDrillDown,
      monthlyAccumulation,
      auditMonth,
    } = item;

    if (!profitVoList || !Array.isArray(profitVoList)) {
      return;
    }

    profitVoList.forEach((profit) => {
      if (!resultMap.has(profit.reportName)) {
        resultMap.set(profit.reportName, {
          ...transformEntry(
            profit,
            computeDate,
            allowDrillDown,
            monthlyAccumulation,
            auditMonth,
          ),
          key: profit.reportName,
        });
      }

      const existingEntry = resultMap.get(profit.reportName)!;
      const transformedProfit = processNode(
        profit,
        computeDate,
        allowDrillDown,
        monthlyAccumulation,
        auditMonth,
      );

      mergeEntries(existingEntry, transformedProfit);

      if (
        transformedProfit.children &&
        Array.isArray(transformedProfit.children)
      ) {
        existingEntry.children = mergeChildren(
          existingEntry.children || [],
          transformedProfit.children,
        );
      }
    });
  });

  // 确保每个层级的数据都有完整的月份字段
  const fillMissingMonths = (nodes: any[], computeDates: string[]) => {
    nodes.forEach((node) => {
      computeDates.forEach((date) => {
        if (!node.hasOwnProperty(`${date}_amount`)) {
          node[`${date}_amount`] =
            node.amount != null
              ? formatMoneyNumber(node.amount, {
                  decimalPlaces: node.decimalPlace,
                  useThousandSeparator: Boolean(node.permil),
                })
              : null;
        }
        if (!node.hasOwnProperty(`${date}_budgetAmount`)) {
          node[`${date}_budgetAmount`] =
            node.budgetAmount != null
              ? formatMoneyNumber(node.budgetAmount, {
                  decimalPlaces: node.decimalPlace,
                  useThousandSeparator: Boolean(node.permil),
                })
              : null;
        }
        if (!node.hasOwnProperty(`${date}_prevPeriodAmount`)) {
          node[`${date}_prevPeriodAmount`] =
            node.prevPeriodAmount != null
              ? formatMoneyNumber(node.prevPeriodAmount, {
                  decimalPlaces: node.decimalPlace,
                  useThousandSeparator: Boolean(node.permil),
                })
              : null;
        }
        if (!node.hasOwnProperty(`${date}_samePeriodAmount`)) {
          node[`${date}_samePeriodAmount`] =
            node.samePeriodAmount != null
              ? formatMoneyNumber(node.samePeriodAmount, {
                  decimalPlaces: node.decimalPlace,
                  useThousandSeparator: Boolean(node.permil),
                })
              : null;
        }
        if (!node.hasOwnProperty(`${date}_completionRate`)) {
          node[`${date}_completionRate`] =
            node.completionRate != null
              ? `${(node.completionRate * 100).toFixed(
                  node.decimalPlace || 2,
                )}%`
              : null;
        }
        if (!node.hasOwnProperty(`${date}_momRate`)) {
          node[`${date}_momRate`] =
            node.momRate != null
              ? `${(node.momRate * 100).toFixed(node.decimalPlace || 2)}%`
              : null;
        }
        if (!node.hasOwnProperty(`${date}_yoyRate`)) {
          node[`${date}_yoyRate`] =
            node.yoyRate != null
              ? `${(node.yoyRate * 100).toFixed(node.decimalPlace || 2)}%`
              : null;
        }
      });

      if (node.children && Array.isArray(node.children)) {
        fillMissingMonths(node.children, computeDates);
        if (node.children.length === 0) {
          delete node.children;
        }
      }
    });
  };

  const computeDates = data.map((item) => item.computeDate);
  const transformedData = Array.from(resultMap.values());
  fillMissingMonths(transformedData, computeDates);

  transformedData.forEach((node) => {
    if (node.children && node.children.length === 0) {
      delete node.children;
    }
  });

  return transformedData;
};

export default function HospitalProfitAndLoss() {
  const location = useLocation();
  // 从路由路径判断模式
  const isYearMode = location.pathname.includes('/year');
  const pageMode = isYearMode ? 'year' : 'month';

  const [tableDataFilterParams, set_tableDataFilterParams] = useState<
    any | undefined
  >({ reportType: 0 });
  const tableRef = useRef<ActionType>();
  const [tabs, set_tabs] = useState<any[]>([]);

  const { initialState, setInitialState } = useModel('@@initialState');
  const [computeRangeDate, set_computeRangeDate] = useState<string[]>(() => {
    if (initialState) {
      if (isYearMode) {
        // 年度模式：使用年份格式
        const year = initialState.computeDate
          ? initialState.computeDate.substring(0, 4)
          : '';
        return [year, year];
      } else {
        // 月度模式：使用原有格式
        return [initialState.computeDate, initialState.computeDate];
      }
    }
    return [];
  });

  const [currentTabKey, set_currentTabKey] = useState<any | undefined>(
    undefined,
  );
  const [currentTab, set_currentTab] = useState<any | undefined>(undefined);
  const [tableDataSearchKeywords, set_tableDataSearchKeywords] = useState('');
  const [allParentsKeys, set_allParentsKeys] = useState<Key[]>([]);
  const [dataSource, set_dataSource] = useState<any[]>([]);
  const [columns, set_columns] = useState<any[]>([]);
  const [showBudgetAndCompletion, set_showBudgetAndCompletion] =
    useState(false);

  // 动态生成列定义函数
  const generateDataColumns = async (data: any[]) => {
    const baseColumns = [
      {
        title: '报表项目名称',
        dataIndex: 'reportName',
        key: 'reportName',
        width: 200,
        fixed: 'left',
      },
    ];

    if (isYearMode) {
      // 年度模式的列配置
      const yearColumns = data.map((item) => {
        const year = item.computeDate;
        const isAuditMonth = item.auditMonth;

        // 如果是审计月，只显示实际金额列
        if (isAuditMonth) {
          return {
            title: `${year}年(审计月)`,
            children: [
              {
                title: '实际',
                dataIndex: `${year}_amount`,
                key: `${year}_amount`,
                width: 150,
                align: 'right',
                renderText(num: number, record: any) {
                  const { calcType } = record;
                  if (calcType == 0) {
                    return <React.Fragment></React.Fragment>;
                  } else {
                    return num;
                  }
                },
              },
            ],
          };
        } else {
          // 非审计月的正常列配置
          const baseYearColumns = [
            {
              title: '实际',
              dataIndex: `${year}_amount`,
              key: `${year}_amount`,
              width: 100,
              align: 'right',
              renderText(num: number, record: any) {
                const { calcType } = record;
                if (calcType == 0) {
                  return <React.Fragment></React.Fragment>;
                } else {
                  return num;
                }
              },
            },
            {
              title: '同期',
              dataIndex: `${year}_samePeriodAmount`,
              key: `${year}_samePeriodAmount`,
              width: 100,
              align: 'right',
              renderText(num: number, record: any) {
                const { calcType } = record;
                if (calcType == 0) {
                  return <React.Fragment></React.Fragment>;
                } else {
                  return num;
                }
              },
            },
            {
              title: '同比',
              dataIndex: `${year}_yoyRate`,
              key: `${year}_yoyRate`,
              width: 100,
              align: 'right',
              renderText(text: string, record: any) {
                const { calcType } = record;
                if (calcType == 0) {
                  return <React.Fragment></React.Fragment>;
                } else {
                  return text;
                }
              },
            },
          ];

          // 根据参数决定是否显示预算和完成率列
          const conditionalColumns = showBudgetAndCompletion
            ? [
                {
                  title: '预算',
                  dataIndex: `${year}_budgetAmount`,
                  key: `${year}_budgetAmount`,
                  width: 100,
                  align: 'right',
                  renderText(num: number, record: any) {
                    const { calcType } = record;
                    if (calcType == 0) {
                      return <React.Fragment></React.Fragment>;
                    } else {
                      return num;
                    }
                  },
                },
                {
                  title: '完成率',
                  dataIndex: `${year}_completionRate`,
                  key: `${year}_completionRate`,
                  width: 100,
                  align: 'right',
                  renderText(text: string, record: any) {
                    const { calcType } = record;
                    if (calcType == 0) {
                      return <React.Fragment></React.Fragment>;
                    } else {
                      return text;
                    }
                  },
                },
              ]
            : [];

          return {
            title: `${year}年`,
            children: [
              ...conditionalColumns.slice(0, 1), // 预算列（如果显示）
              ...baseYearColumns.slice(0, 1), // 实际列
              ...baseYearColumns.slice(1, 2), // 同期列
              ...conditionalColumns.slice(1, 2), // 完成率列（如果显示）
              ...baseYearColumns.slice(2, 3), // 同比列
            ],
          };
        }
      });
      set_columns([...baseColumns, ...yearColumns]);
    } else {
      // 月度模式的列配置
      const monthColumns = data.map((item) => {
        const month = item.computeDate;
        const isMonthlyAccumulation = item.monthlyAccumulation;
        const isAuditMonth = item.auditMonth;

        // 构建最终的列数组
        let finalColumns: any[] = [];

        // 如果是审计月，只显示实际金额列
        if (isAuditMonth) {
          finalColumns.push({
            title: '实际',
            dataIndex: `${month}_amount`,
            key: `${month}_amount`,
            width: 150,
            align: 'right',
            renderText(num: number, record: any) {
              const { calcType } = record;
              if (calcType == 0) {
                return <React.Fragment></React.Fragment>;
              } else {
                return num;
              }
            },
          });
        } else {
          // 非审计月的正常列配置
          // 根据参数决定是否显示预算列（放在实际列前面）
          if (showBudgetAndCompletion) {
            finalColumns.push({
              title: '预算',
              dataIndex: `${month}_budgetAmount`,
              key: `${month}_budgetAmount`,
              width: 100,
              align: 'right',
              renderText(num: number, record: any) {
                const { calcType } = record;
                if (calcType == 0) {
                  return <React.Fragment></React.Fragment>;
                } else {
                  return num;
                }
              },
            });
          }

          // 添加实际列
          finalColumns.push({
            title: '实际',
            dataIndex: `${month}_amount`,
            key: `${month}_amount`,
            width: 100,
            align: 'right',
            renderText(num: number, record: any) {
              const { calcType } = record;
              if (calcType == 0) {
                return <React.Fragment></React.Fragment>;
              } else {
                return num;
              }
            },
          });

          // 始终显示上期列
          finalColumns.push({
            title: '上期',
            dataIndex: `${month}_prevPeriodAmount`,
            key: `${month}_prevPeriodAmount`,
            width: 100,
            align: 'right',
            renderText(num: number, record: any) {
              const { calcType } = record;
              if (calcType == 0) {
                return <React.Fragment></React.Fragment>;
              } else {
                return num;
              }
            },
          });

          // 始终显示同期列
          finalColumns.push({
            title: '同期',
            dataIndex: `${month}_samePeriodAmount`,
            key: `${month}_samePeriodAmount`,
            width: 100,
            align: 'right',
            renderText(num: number, record: any) {
              const { calcType } = record;
              if (calcType == 0) {
                return <React.Fragment></React.Fragment>;
              } else {
                return num;
              }
            },
          });

          // 根据参数决定是否显示完成率列
          if (showBudgetAndCompletion) {
            finalColumns.push({
              title: '完成率',
              dataIndex: `${month}_completionRate`,
              key: `${month}_completionRate`,
              width: 100,
              align: 'right',
              renderText(text: any, record: any) {
                const { calcType } = record;
                if (calcType == 0) {
                  return <React.Fragment></React.Fragment>;
                } else {
                  return text;
                }
              },
            });
          }

          // 始终显示环比列
          finalColumns.push({
            title: '环比增长',
            dataIndex: `${month}_momRate`,
            key: `${month}_momRate`,
            width: 100,
            align: 'right',
            renderText(text: any, record: any) {
              const { calcType } = record;
              if (calcType == 0) {
                return <React.Fragment></React.Fragment>;
              } else {
                return text;
              }
            },
          });

          // 始终显示同比列
          finalColumns.push({
            title: '同比增长',
            dataIndex: `${month}_yoyRate`,
            key: `${month}_yoyRate`,
            width: 100,
            align: 'right',
            renderText(text: any, record: any) {
              const { calcType } = record;
              if (calcType == 0) {
                return <React.Fragment></React.Fragment>;
              } else {
                return text;
              }
            },
          });
        }

        // 构建月份标题，包含特殊标志
        let monthTitle = month;
        if (isMonthlyAccumulation) {
          monthTitle += '(月累计)';
        }
        if (isAuditMonth) {
          monthTitle += '(审计月)';
        }

        return {
          title: monthTitle,
          children: finalColumns,
        };
      });
      set_columns([...baseColumns, ...monthColumns]);
    }
  };

  // 前端检索函数
  const filterDataByKeyword = (data: any[], keyword: string): any[] => {
    if (!keyword || keyword.trim() === '') {
      return data;
    }

    const filterNode = (node: any): any | null => {
      // 检查当前节点是否匹配
      const isMatch =
        node.reportName &&
        node.reportName.toLowerCase().includes(keyword.toLowerCase());

      // 递归过滤子节点
      let filteredChildren: any[] = [];
      if (node.children && Array.isArray(node.children)) {
        filteredChildren = node.children
          .map(filterNode)
          .filter((child: any) => child !== null);
      }

      // 如果当前节点匹配或有匹配的子节点，则保留该节点
      if (isMatch || filteredChildren.length > 0) {
        return {
          ...node,
          children: filteredChildren.length > 0 ? filteredChildren : undefined,
        };
      }

      return null;
    };

    return data.map(filterNode).filter((node: any) => node !== null);
  };

  const getTableData = async (params: any) => {
    const { beginComputeDate, endComputeDate, reportType, filter } = params;
    if (!beginComputeDate || !endComputeDate || reportType === undefined) {
      // 参数不完整时，清空数据并返回空结果
      set_dataSource([]);
      set_columns([
        {
          title: '报表项目名称',
          dataIndex: 'reportName',
          key: 'reportName',
          width: 200,
          fixed: 'left',
        },
      ]);
      return {
        data: [],
        success: true,
      };
    }

    try {
      const resp = await getBatchHospProfitList({
        beginComputeDate,
        endComputeDate,
        reportType,
      });

      if (resp) {
        const realData = transformData(resp);
        // 应用前端检索过滤
        const filteredData = filterDataByKeyword(realData, filter || '');
        generateDataColumns(resp);
        set_dataSource(filteredData);
        return {
          data: filteredData,
          success: true,
        };
      } else {
        // 请求成功但没有数据
        generateDataColumns([]);
        set_dataSource([]);
        return {
          data: [],
          success: true,
        };
      }
    } catch (error) {
      // 请求失败时，清空数据并返回错误状态
      console.error('获取数据失败:', error);
      set_dataSource([]);
      set_columns([
        {
          title: '报表项目名称',
          dataIndex: 'reportName',
          key: 'reportName',
          width: 200,
          fixed: 'left',
        },
      ]);
      return {
        data: [],
        success: false,
        error: error,
      };
    }
  };

  const onTabChanged = (key: Key) => {
    set_currentTabKey(key);
    const needItem = tabs.filter((a) => a.key == key);
    if (needItem.length > 0) set_currentTab(needItem[0]);
    // 切换tab时立即清空数据源，避免显示上一个tab的数据
    set_dataSource([]);
    // 同时清空列定义，避免显示错误的列结构
    set_columns([
      {
        title: '报表项目名称',
        dataIndex: 'reportName',
        key: 'reportName',
        width: 200,
        fixed: 'left',
      },
    ]);
  };

  const getTabs = async () => {
    const { systemId } = JSON.parse(
      localStorage.getItem('currentSelectedTab') as string,
    );
    const resp = await getDicDataBySysId(systemId, 'PROFIT_REPORT_TYPE');
    if (resp) {
      const { dataVoList } = resp;
      // 过滤只显示value字段等于2的字典项
      const filteredDataVoList = dataVoList.filter((a: any) => a.value === '2');
      const tempArr = filteredDataVoList.map((a: any) => ({
        label: a.name,
        key: Number(a.code),
        value: a.value,
      }));
      set_tabs([...tempArr]);
      set_currentTabKey(tempArr[0].key);
      set_currentTab(tempArr[0]);
    }
  };

  const getShowBudgetAndCompletion = async () => {
    const { systemId } = JSON.parse(
      localStorage.getItem('currentSelectedTab') as string,
    );
    const resp = await getParamsDataBySysId(systemId, '1942871277190647808');
    if (resp) {
      set_showBudgetAndCompletion(resp.value === '1');
    }
  };

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

  const getHeaderRows = (
    columns: any[],
    level = 0,
    headerRows: any[] = [],
    maxLevel = 0,
  ) => {
    headerRows[level] = headerRows[level] || [];
    columns.forEach((col: { title: any; children: any }) => {
      const colSpan = getColSpan(col);
      headerRows[level].push({
        title: col.title,
        colSpan,
        rowSpan: col.children ? 1 : maxLevel - level,
      });
      if (col.children) {
        getHeaderRows(col.children, level + 1, headerRows, maxLevel);
      } else {
        // 填充空白单元格
        for (let i = level + 1; i < maxLevel; i++) {
          headerRows[i] = headerRows[i] || [];
          headerRows[i].push({ title: '', colSpan: 1, rowSpan: 1 });
        }
      }
    });
    return headerRows;
  };

  const getColSpan: any = (col: { children: any[] }) => {
    if (!col.children) return 1;
    return col.children.reduce((sum, child) => sum + getColSpan(child), 0);
  };

  const getMaxLevel = (col: any) => {
    if (!col.children) return 1;
    return 1 + Math.max(...col.children.map(getMaxLevel));
  };

  const extractLeafColumns = (columns: any[]) => {
    let leafColumns: any[] = [];
    columns.forEach((col) => {
      if (col.children) {
        leafColumns = leafColumns.concat(extractLeafColumns(col.children));
      } else {
        leafColumns.push(col);
      }
    });
    return leafColumns;
  };

  const addRowWithIndentation = (
    record: any,
    level: number,
    leafColumns: any[],
    worksheetData: any[],
    dataRowColors: string[],
  ) => {
    const row = leafColumns.map((col) => record[col.dataIndex] ?? '');
    row[0] = ' '.repeat(level * 4) + row[0]; // 在第一列前添加缩进空格以表示层级
    worksheetData.push(row);
    dataRowColors.push(getReportFontColor(record));
    if (record.children) {
      record.children.forEach((child: any) =>
        addRowWithIndentation(
          child,
          level + 1,
          leafColumns,
          worksheetData,
          dataRowColors,
        ),
      );
    }
  };

  const handleExport = () => {
    try {
      const workbook = XLSX.utils.book_new();
      const worksheetData: any[] = [];

      // 获取最大层级
      const maxLevel = columns.reduce(
        (max, col) => Math.max(max, getMaxLevel(col)),
        0,
      );

      // 生成多层级表头
      const headerRows = getHeaderRows(columns, 0, [], maxLevel);

      // 构建表头行
      headerRows.forEach((row: any, rowIndex) => {
        const rowData: string[] = [];
        row.forEach(
          (cell: { title: any; colSpan: number; rowSpan: number }) => {
            rowData.push(cell.title);
            for (let i = 1; i < cell.colSpan; i++) {
              rowData.push('');
            }
          },
        );
        worksheetData.push(rowData);
      });

      // 填充单层表头的空白行
      if (maxLevel > 1) {
        const numColumns = headerRows[0].reduce(
          (sum: any, cell: { colSpan: any }) => sum + cell.colSpan,
          0,
        );
        for (let i = 1; i < maxLevel; i++) {
          while (worksheetData[i].length < numColumns) {
            worksheetData[i].push('');
          }
        }
      }

      // 提取最内层表头列
      const leafColumns = extractLeafColumns(columns);
      const dataRowColors: string[] = [];

      // 添加数据并处理树结构
      dataSource.forEach((record) =>
        addRowWithIndentation(
          record,
          0,
          leafColumns,
          worksheetData,
          dataRowColors,
        ),
      );

      const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);

      // 初始化合并单元格数组
      worksheet['!merges'] = worksheet['!merges'] || [];

      // 合并单元格
      headerRows.forEach((row: any, rowIndex) => {
        let colIndex = 0;
        row.forEach((cell: { colSpan: number; rowSpan: number }) => {
          if (cell.colSpan > 1 || cell.rowSpan > 1) {
            worksheet['!merges']!.push({
              s: { r: rowIndex, c: colIndex },
              e: {
                r: rowIndex + cell.rowSpan - 1,
                c: colIndex + cell.colSpan - 1,
              },
            });
          }
          colIndex += cell.colSpan;
        });
      });

      // 设置单元格对齐方式
      Object.keys(worksheet).forEach((cell) => {
        if (cell[0] !== '!') {
          worksheet[cell].s = {
            alignment: { vertical: 'center', horizontal: 'center' },
          };
        }
      });

      const headerRowsCount = headerRows.length;
      dataRowColors.forEach((rowColor, index) => {
        const excelArgb = convertToExcelArgb(rowColor);
        const rowIndex = headerRowsCount + index;
        for (let colIndex = 0; colIndex < leafColumns.length; colIndex++) {
          const cellRef = XLSX.utils.encode_cell({ r: rowIndex, c: colIndex });
          if (!worksheet[cellRef]) continue;
          const prevStyle = worksheet[cellRef].s || {};
          worksheet[cellRef].s = {
            ...prevStyle,
            font: { ...(prevStyle.font || {}), color: { rgb: excelArgb } },
            alignment: prevStyle.alignment || {
              vertical: 'center',
              horizontal: 'center',
            },
          };
        }
      });

      XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
      XLSX.writeFile(
        workbook,
        currentTab ? `${currentTab.label}.xlsx` : '全院损益报表.xlsx',
      );
    } catch (error) {
      console.error('导出失败:', error);
      message.error('导出失败');
    }
  };

  const handleExpandNext = () => {
    // 当前所有未展开的节点，第一层优先展开
    const keysToExpand = getNextUnexpandedKeys(dataSource, allParentsKeys);
    set_allParentsKeys((prev) =>
      Array.from(new Set([...prev, ...keysToExpand])),
    );
  };

  const handleCollapseAll = () => {
    set_allParentsKeys([]);
  };

  // 根据ID查找节点
  const findNodeById = (data: any[], nodeId: any): any => {
    for (const node of data) {
      if (node.reportId === nodeId) {
        return node;
      }
      if (node.children) {
        const found = findNodeById(node.children, nodeId);
        if (found) return found;
      }
    }
    return null;
  };

  // 获取节点的所有子节点ID
  const getAllChildrenIds = (node: any): any[] => {
    let ids: any[] = [];
    if (node.children) {
      node.children.forEach((child: any) => {
        ids.push(child.reportId);
        ids = ids.concat(getAllChildrenIds(child));
      });
    }
    return ids;
  };

  const getNextUnexpandedKeys = (data: any[], expandedKeys: any[] = []) => {
    let keys: any[] = [];

    const traverse = (nodes: any) => {
      for (const node of nodes) {
        // 如果当前节点还没有展开，就把它加入 keys
        if (!expandedKeys.includes(node.reportId)) {
          keys.push(node.reportId);
        }

        // 如果当前节点已经展开，继续遍历子节点
        if (node.children && expandedKeys.includes(node.reportId)) {
          traverse(node.children);
        }
      }
    };

    traverse(data);

    return keys;
  };

  useEffect(() => {
    if (computeRangeDate && currentTabKey != undefined) {
      set_allParentsKeys([]);
    }
  }, [computeRangeDate, currentTabKey]);

  useEffect(() => {
    if (currentTabKey !== undefined) {
      if (isYearMode) {
        // 年度模式：确保传递的是纯年份
        const startYear = computeRangeDate[0]
          ? computeRangeDate[0].substring(0, 4)
          : '';
        const endYear = computeRangeDate[1]
          ? computeRangeDate[1].substring(0, 4)
          : '';
        set_tableDataFilterParams({
          ...tableDataFilterParams,
          reportType: currentTabKey,
          beginComputeDate: startYear,
          endComputeDate: endYear,
        });
      } else {
        set_tableDataFilterParams({
          ...tableDataFilterParams,
          reportType: currentTabKey,
          beginComputeDate: computeRangeDate[0],
          endComputeDate: computeRangeDate[1],
        });
      }
    }
    set_allParentsKeys([]);
  }, [currentTabKey, computeRangeDate]);

  useEffect(() => {
    getTabs();
    getShowBudgetAndCompletion();
  }, []);

  return (
    <KCIMPagecontainer className="HospitalProfitAndLoss" title={false}>
      <div className="header">
        <div className="search">
          <span>{isYearMode ? '核算年份：' : '核算年月：'}</span>
          <RangePicker
            onChange={(data, dateString) => {
              set_computeRangeDate(dateString);
              setInitialState((s: any) => ({
                ...s,
                computeDate: dateString[0],
              }));
              if (isYearMode) {
                // 年度模式：提取年份部分
                const startYear =
                  data?.[0]?.year()?.toString() || dateString[0];
                const endYear = data?.[1]?.year()?.toString() || dateString[1];
                set_tableDataFilterParams({
                  ...tableDataFilterParams,
                  beginComputeDate: startYear,
                  endComputeDate: endYear,
                });
              } else {
                set_tableDataFilterParams({
                  ...tableDataFilterParams,
                  beginComputeDate: dateString[0],
                  endComputeDate: dateString[1],
                });
              }
            }}
            picker={isYearMode ? 'year' : 'month'}
            locale={locale}
            autoComplete="off"
            defaultValue={
              isYearMode
                ? [
                    moment(computeRangeDate[0], 'YYYY'),
                    moment(computeRangeDate[1], 'YYYY'),
                  ]
                : [
                    moment(computeRangeDate[0], 'YYYY-MM'),
                    moment(computeRangeDate[1], 'YYYY-MM'),
                  ]
            }
            format={isYearMode ? 'YYYY' : 'YYYY-MM'}
          />
        </div>
      </div>
      <div className="content">
        <Tabs
          defaultActiveKey={tabs.length > 0 ? tabs[0].key : undefined}
          items={tabs}
          key={'key'}
          onChange={(key) => onTabChanged(key)}
        />
        <div className="inner">
          <div className="right">
            <div className="toolBar">
              <div className="filterItem" style={{ width: 228 }}>
                <span className="label" style={{ whiteSpace: 'nowrap' }}>
                  {' '}
                  检索：
                </span>
                <Input
                  placeholder={'报表项目代码/名称'}
                  allowClear
                  autoComplete="off"
                  suffix={
                    <IconFont
                      type="iconsousuo"
                      style={{ color: '#99A6BF' }}
                      onClick={() => tableDataSearchHandle('filter')}
                    />
                  }
                  onChange={(e) => {
                    set_tableDataSearchKeywords(e.target.value);
                    if (e.target.value.length == 0) {
                      set_tableDataFilterParams({
                        ...tableDataFilterParams,
                        filter: '',
                      });
                    }
                  }}
                  onPressEnter={(e) => {
                    set_tableDataFilterParams({
                      ...tableDataFilterParams,
                      filter: (e.target as HTMLInputElement).value,
                    });
                  }}
                />
              </div>
              <div className="btnGroup">
                <span className="btn" onClick={() => handleCollapseAll()}>
                  全部折叠
                </span>
                <span
                  className="btn"
                  style={{ marginRight: 16 }}
                  onClick={() => handleExpandNext()}
                >
                  展开下一层
                </span>
                <span className="calc" onClick={() => handleExport()}>
                  导出
                </span>
              </div>
            </div>

            <KCIMTable
              pagination={false}
              bordered
              rowClassName={(record) =>
                `${
                  record.children ? 'has-children ' : ''
                }hover-row report-font-color-row`
              }
              onRow={(record: any) => ({
                style: {
                  ['--report-font-color' as any]: getReportFontColor(record),
                } as React.CSSProperties,
              })}
              expandable={{
                defaultExpandAllRows: false,
                expandedRowKeys: allParentsKeys,
                onExpand(expanded, record) {
                  const { reportId } = record;
                  if (!expanded) {
                    // 收起时，移除当前节点及其所有子节点
                    const removeNodeAndChildren = (
                      nodeId: any,
                      keys: any[],
                    ) => {
                      const node = findNodeById(dataSource, nodeId);
                      if (node) {
                        const childrenIds = getAllChildrenIds(node);
                        return keys.filter(
                          (key) => key !== nodeId && !childrenIds.includes(key),
                        );
                      }
                      return keys.filter((key) => key !== nodeId);
                    };
                    set_allParentsKeys(
                      removeNodeAndChildren(reportId, allParentsKeys),
                    );
                  } else {
                    // 展开时，只添加当前节点
                    set_allParentsKeys([...allParentsKeys, reportId]);
                  }
                },
              }}
              columns={columns as ProColumns[]}
              scroll={{ y: `calc(100vh - 343px)` }}
              actionRef={tableRef}
              rowKey="reportId"
              params={tableDataFilterParams}
              request={(params) => getTableData(params)}
            />
          </div>
        </div>
      </div>
    </KCIMPagecontainer>
  );
}
