/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2022-12-14 14:14:32
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2025-04-11 15:50:16
 * @FilePath: /BudgetManaSystem/src/app.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
// 运行时配置

// 打印版本信息（在模块加载时立即执行）
(function printVersion() {
  console.log(
    '%c 成本核算系统 %c v' +
      process.env.APP_VERSION +
      ' %c 构建时间：' +
      process.env.BUILD_TIME +
      ' ',
    'background: #3377FF; color: #fff; padding: 2px 6px; border-radius: 3px 0 0 3px;',
    'background: #35495e; color: #fff; padding: 2px 6px;',
    'background: #41b883; color: #fff; padding: 2px 6px; border-radius: 0 3px 3px 0;',
  );
})();

// 全局初始化数据配置，用于 Layout 用户信息和权限初始化
// 更多信息见文档：https://next.umijs.org/docs/api/runtime-config#getinitialstate

import { AxiosResponse, history } from '@umijs/max';
import { message, notification, Modal, Menu } from 'antd';
import type { RequestConfig } from 'umi';

import iconEnum from './menuIcons.js';

// import Report from './pages/reports/index';
import Static from './pages/static/index';

import DevicePixelRatio from './utils/devicePixelRatio.js';

import Icon, { createFromIconfontCN, FolderOutlined } from '@ant-design/icons';
import { getLastComputeDate, getPlatformMenu } from '@/services/auth';
import {
  JSXElementConstructor,
  Key,
  ReactElement,
  ReactFragment,
  ReactPortal,
  useEffect,
  useRef,
  useState,
} from 'react';

import './utils/zhongtaiC';
import { RuntimeAntdConfig } from '@umijs/max';
import { useLocation } from '@umijs/max';
import ResizableContainer from './components/ResizableContainer/index';
import { IRoute } from '@umijs/max';

// 权限检查函数
function checkAccess(menu: IRoute[], pathname: string): boolean {
  for (const item of menu) {
    if (item.path === pathname) {
      return true;
    }
    if (item.children) {
      const hasAccess = checkAccess(item.children, pathname);
      if (hasAccess) {
        return true;
      }
    }
  }
  return false;
}

function removePrefix(input: string, prefix: string): string {
  if (input.startsWith(prefix)) {
    return input.slice(prefix.length);
  }
  return input;
}

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

// 错误处理方案： 错误类型
enum ErrorShowType {
  SILENT = 0,
  WARN_MESSAGE = 1,
  ERROR_MESSAGE = 2,
  NOTIFICATION = 3,
  REDIRECT = 9,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
  success?: boolean;
  code?: string;
  data: any;
  errorCode?: number;
  errorMessage?: string;
  showType?: ErrorShowType;
}

interface UserData {
  name?: string;
  ruleVersion?: string;
  token?: string;
  userId?: number;
  youshuToken?: string;
}

interface TransformResult {
  newTree: any[];
  firstLeafNode: any | null;
  firstLeafNodePath: any[];
}

function transformTree(tree: any[]): TransformResult {
  let firstLeafNode: any | null = null;
  let firstLeafNodePath: any[] = [];

  function traverse(node: any, path: any[]): any {
    const newNode: any = {
      ...node,
      label: node.name,
    };

    const newPath = [...path, newNode];

    if (node.children && node.children.length > 0) {
      newNode.children = node.children.map((child: any) =>
        traverse(child, newPath),
      );
    } else {
      if (!firstLeafNode) {
        firstLeafNode = newNode;
        firstLeafNodePath = newPath;
      }
    }

    // Remove children property if it is an empty array
    if (node.children && node.children.length === 0) {
      newNode.children = null;
    }

    return newNode;
  }

  const newTree = tree.map((node) => traverse(node, []));

  return { newTree, firstLeafNode, firstLeafNodePath };
}

const findItemByKey: any = (tree: any[], key: string, keyName: string) => {
  for (const node of tree) {
    if (node[`${keyName}`] === key) {
      return node;
    }
    if (node.children) {
      const result = findItemByKey(node.children, key, keyName);
      if (result) {
        return result;
      }
    }
  }
  return null;
};

export async function getInitialState(): Promise<{
  isCollapsed: boolean;
  spacicalPageParamsType?: any[];
  userData: UserData;
  memuData: any[];
  computeDate: string;
}> {
  new DevicePixelRatio().init();

  // 默认的计算日期
  let computeDate = `${new Date().getFullYear()}-${(new Date().getMonth() + 1)
    .toString()
    .padStart(2, '0')}`;

  try {
    // 获取最新计算日期的请求
    const resp = await getLastComputeDate();
    if (resp) {
      computeDate = resp; // 更新计算日期
    }
  } catch (error) {
    console.error('获取计算日期失败:', error); // 捕获和处理错误
  }

  // 返回状态
  return {
    isCollapsed: false,
    spacicalPageParamsType: [],
    userData: {},
    memuData: [],
    computeDate: computeDate,
  };
}

export const request: RequestConfig = {
  // 统一的请求设定
  timeout: 100000000,
  headers: { 'X-Requested-With': 'XMLHttpRequest' },
  // transformResponse:[function (data) {
  //   try {
  //     // 如果转换成功则返回转换的数据结果
  //     return JSONbig.parse(data);
  //   } catch (error) {
  //     // 如果转换失败，则包装为统一数据格式并返回
  //     return data
  //   }
  // }],
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: (res: ResponseStructure) => {
      const { success, data, errorCode, errorMessage, showType } = res;
      console.log({ success, data, errorCode, errorMessage, showType });
      if (!success) {
        const error: any = new Error(errorMessage);
        error.name = 'BizError';
        error.info = { errorCode, errorMessage, showType, data };
        throw error; // 抛出自制的错误
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestConfig) => {
      // 拦截请求配置，进行个性化处理。
      const userData = localStorage.getItem('userData');
      const { token = '' } = JSON.parse(userData as any);
      return { ...config, url: `/gateway${config.url}`, headers: { token } };
      // return { ...config }
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response: AxiosResponse) => {
      // 拦截响应数据，进行个性化处理
      const {
        status,
        data: { status: code, errorMessage, msg },
        config: { method },
      } = response;

      try {
        if (status == 200) {
          // 网络请求成功
          if (errorMessage && errorMessage.indexOf('Token') != -1) {
            console.log({ response, errorMessage });
            localStorage.removeItem('tokenExpired');

            return false;
          }

          if (method == 'post') {
            if (code == 200) {
              return response.data.data == null
                ? {
                    success: true,
                    data: true,
                  }
                : response.data;
            } else {
              notification.error({
                top: 72,
                message: '提示',
                description: errorMessage || msg,
                placement: 'topRight',
                icon: <IconFont type="icon-jinggaotishi" />,
                style: { padding: 16, borderRadius: 8 },
              });
              return false;
            }
          } else {
            if (status != 200) {
              message.error('请求失败！');
              return false;
            } else {
              if (code == 200) {
                //console.log({code,'response.data':response.data});
                return response.data;
              } else {
                notification.error({
                  top: 72,
                  message: '提示',
                  description: errorMessage || msg,
                  placement: 'topRight',
                  icon: <IconFont type="icon-jinggaotishi" />,
                  style: { padding: 16, borderRadius: 8 },
                });
                return false;
              }
            }
          }
        } else {
          return false;
        }
      } catch (error) {
        console.log({ error });
      }
    },
  ],
};

export type menuDataItemType = {
  path: string;
  name: string;
  icon: any;
  component?: string;
  softUrl?: string; // 帆软url
  children?: menuDataItemType[];
};

// 将服务端获取的菜单 icon 字符串映射为对应的 icon Dom
const mappingIcon = (menuData: menuDataItemType[]) => {
  if (menuData.length == 0) {
    return [
      {
        path: '',
        name: '',
        icon: '',
        component: './404',
      },
    ];
  }
  const mappingMenu: menuDataItemType[] = menuData.map((item) => ({
    ...item,
    icon: item.icon && iconEnum[item.icon],
    children: item.children ? mappingIcon(item.children) : [],
  }));
  return mappingMenu;
};

const imgNode = (props: any) => {
  return <IconFont type="icon-shouye" {...props} />;
};
const fileIcon = () => {
  return <IconFont type="icon-jixiaoguanli" />;
};

const setting = () => {
  return <IconFont type="icon-xitongshezhi" />;
};

const secondaryDistribute = () => {
  return <IconFont type="icon-ercifenpei" />;
};

const reportCheck = () => {
  return <IconFont type="icon-baobiaochaxun" />;
};

export function patchClientRoutes({ routes }: { routes: any }) {
  const treeLoop = (treeData: any) => {
    if (treeData.routes) {
      const paths = [...new Array(10).keys()].map((a, index) => ({
        path: `${treeData.path == '/' ? '' : treeData.path}/reports/${index}`,
        exact: true,
        element: <Static />,
      }));

      const lanhuPagePaths = [...new Array(5).keys()].map((a, index) => ({
        path: `${treeData.path == '/' ? '' : treeData.path}/static/${index}`,
        exact: true,
        element: <Static />,
      }));

      paths.forEach((a: any) => {
        treeData.routes.push(a);
      });

      lanhuPagePaths.forEach((a: any) => {
        treeData.routes.push(a);
      });
    }
    if (treeData.routes && treeData.routes.length > 0) {
      treeData.routes.forEach((a: any) => {
        treeLoop(a);
      });
    }
  };

  treeLoop(routes[0]);

  console.log({ routes });
}

//布局配置

export const layout = ({
  initialState,
  setInitialState,
}: {
  initialState: any;
  setInitialState: any;
}) => {
  const { isCollapsed } = initialState;

  const location = useLocation();
  const currentPath = location.pathname;
  const isMenuClickRef = useRef(false);

  const onCollapse = (isCollapsed: boolean): void => {
    setInitialState({ ...initialState, isCollapsed }).then();
  };

  const checkPermission = (path: string) => {
    const { memuData = [] } = initialState || {};
    // 检查是否为无访问权限页面
    if (path === '/noAccess') {
      return true;
    }

    // 检查访问权限
    const hasAccess = checkAccess([...memuData], path);

    return hasAccess;
  };

  // useEffect(() => {
  //   return history.listen((location: any) => {
  //     if (!isMenuClickRef.current) {
  //       const path = removePrefix(location.location.pathname, '/CostAccountingSys');
  //       const hasPermission = checkPermission(path);
  //       console.log({ hasPermission, path });

  //       // 如果hasPermission为true，确保不会跳转到/noAccess
  //       if (!hasPermission && path !== '/noAccess') {
  //         history.push('/noAccess');
  //       }
  //     }
  //     isMenuClickRef.current = false; // 重置状态
  //   });
  // }, [initialState]);

  return {
    menuHeaderRender: false,
    disableMobile: true,
    onPageChange: () => {},
    collapsedButtonRender: () => {
      return (
        <div
          style={{
            position: 'absolute',
            zIndex: 10,
            right: 17,
            bottom: 12,
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            cursor: 'pointer',
            width: 24,
            height: 24,
          }}
          onClick={() => {
            onCollapse(isCollapsed ? false : true);
          }}
        >
          <IconFont
            className="menuCollapseIcon"
            type={isCollapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'}
          />
        </div>
      );
    },
    collapsed: isCollapsed,
    // fixSiderbar:false,
    menuItemRender: (
      item: { path: any },
      dom:
        | string
        | number
        | boolean
        | ReactElement<any, string | JSXElementConstructor<any>>
        | ReactFragment
        | ReactPortal
        | null
        | undefined,
    ) => {
      return (
        <a
          onClick={() => {
            isMenuClickRef.current = true; // 标记为菜单点击
            history.push(`${item.path}`);
          }}
        >
          {dom}
        </a>
      );
    },
    menu: {
      request: async () => {
        const userData = localStorage.getItem('userData');
        const currentSelectedTab = localStorage.getItem('currentSelectedTab');
        if (currentSelectedTab) {
          const { menuId } = JSON.parse(currentSelectedTab);
          const systemId = menuId;
          const data: any[] = await getPlatformMenu(systemId);
          if (data) {
            function processMenuItem(item: any) {
              if (!item) return null;

              let newItem = { ...item }; // 深拷贝当前节点

              // 如果是叶子节点
              if (!item.children || item.children.length === 0) {
                let queryParams = [];

                if (newItem.softUrl) {
                  queryParams.push(`softUrl=${newItem.softUrl}`);
                }

                if (newItem.youshuUrl) {
                  queryParams.push(`youshuUrl=${newItem.youshuUrl}`);
                }

                if (queryParams.length > 0) {
                  newItem.path = `${newItem.path}?${queryParams.join('&')}`;
                }

                return newItem; // 返回新的叶子节点
              }

              // 否则，递归处理子节点
              newItem.children = newItem.children.map(processMenuItem);
              return newItem;
            }

            function processMenu(menuArray: any[]) {
              if (!menuArray) return [];
              return menuArray.map(processMenuItem);
            }

            const _menu = processMenu(data);

            setInitialState((t: any) => ({
              ...t,
              spacicalPageParamsType: _menu,
              memuData: data,
              userData: JSON.parse(userData as string),
            }));

            function addIconToPath(node: any, paths: string[]) {
              if (paths.includes(node.path)) {
                if (node.path == '/home') {
                  node.icon = <Icon component={imgNode} />;
                }
                if (node.path == '/baseSetting') {
                  node.icon = <Icon component={setting} />;
                }
                if (node.path == '/monthlyInfoSearch') {
                  node.icon = (
                    <Icon
                      component={() => <IconFont type="icon-yueduxinxicaiji" />}
                    />
                  );
                }
                if (node.path == '/costAccounting') {
                  node.icon = (
                    <Icon
                      component={() => <IconFont type="icon-jixiaoguanli" />}
                    />
                  );
                }
                // 新增：standardCostReport 使用与 /costAccounting 相同的 icon
                if (node.path == '/standardCostReport') {
                  node.icon = (
                    <Icon
                      component={() => <IconFont type="icon-jixiaoguanli" />}
                    />
                  );
                }
                if (node.path == '/reportExport') {
                  node.icon = (
                    <Icon
                      component={() => <IconFont type="icon-jixiaoguanli" />}
                    />
                  );
                }
                if (node.path == '/costLibraryManagement') {
                  node.icon = (
                    <Icon
                      component={() => (
                        <IconFont type="icon-chengbenkuguanli" />
                      )}
                    />
                  );
                }
                if (node.path == '/static') {
                  node.icon = (
                    <Icon
                      component={() => <IconFont type="icon-baobiaochaxun" />}
                    />
                  );
                }
              }
              // 目录默认 icon：无 icon 且有子节点时使用文件夹图标
              if (
                !node.icon &&
                Array.isArray(node.children) &&
                node.children.length > 0
              ) {
                node.icon = <FolderOutlined />;
              }
              if (node.children) {
                node.children.forEach((child: any) =>
                  addIconToPath(child, paths),
                );
              }
            }

            _menu.forEach((item: any) => {
              addIconToPath(item, [
                '/home',
                '/baseInfoMana',
                '/costAccounting',
                '/standardCostReport',
                '/monthlyInfoSearch',
                '/static',
                '/reportExport',
                '/costLibraryManagement',
                '/baseSetting',
              ]);
            });

            const { newTree, firstLeafNode, firstLeafNodePath } =
              transformTree(_menu);

            // console.log({newTree});

            return newTree;
          }
        }
      },
    },
    menuRender: (props: any, defaultDom: any) => {
      return (
        <ResizableContainer
          width={isCollapsed ? 64 : 200}
          minWidth={0}
          maxWidth={600}
          height={'calc(100vh - 47px)'}
        >
          <div
            style={{ height: '100%', background: '#fff', position: 'relative' }}
          >
            <div
              className="menuWrapper"
              style={{
                height: 'calc(100% - 40px)',
                overflowY: 'scroll',
                overflowX: 'hidden',
              }}
            >
              {defaultDom}
            </div>

            <div
              style={{
                position: 'absolute',
                zIndex: 10,
                right: 17,
                bottom: 9,
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center',
                cursor: 'pointer',
                width: 24,
                height: 24,
              }}
              onClick={() => {
                onCollapse(isCollapsed ? false : true);
              }}
            >
              <IconFont
                className="menuCollapseIcon"
                type={isCollapsed ? 'icon-celanzhankai' : 'icon-celanshouqi'}
              />
            </div>
          </div>
        </ResizableContainer>
      );
    },
    contentStyle: {
      // border: '16px solid #F7F9FC',
      //height: '94.5vh',  //以去除顶部导航高度
      borderRadius: '22px',
      background: '#F7F9FC',
      height: 'calc(100vh - 48px)',
      // overflow:'scroll',
      // margin:'20px 20px'
    },
  };
};
