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

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

import { AxiosResponse, history } from '@umijs/max';
import { message, notification } 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 { getPlatformMenu } from '@/services/auth';
import { Key, useState } from 'react';

import './utils/zhongtaiC';
import { RuntimeAntdConfig } from '@umijs/max';

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;
}

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

  return {
    isCollapsed: false,
    spacicalPageParamsType: [],
    userData: {},
    memuData: [],
  };
}

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;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const errorInfo: ResponseStructure | undefined = error.info;
        if (errorInfo) {
          const { errorMessage, errorCode } = errorInfo;
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
              break;
            case ErrorShowType.WARN_MESSAGE:
              message.warning(errorMessage);
              break;
            case ErrorShowType.ERROR_MESSAGE:
              message.error(errorMessage);
              break;
            case ErrorShowType.NOTIFICATION:
              notification.open({
                description: errorMessage,
                message: errorCode,
              });
              break;
            case ErrorShowType.REDIRECT:
              // TODO: redirect
              break;
            default:
              message.error(errorMessage);
          }
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        message.error(`Response status:${error.response.status}`);
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('None response! Please retry.');
      } else {
        // 发送请求时出了点问题
        message.error('Request error, please retry.');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestConfig) => {
      // 从 localStorage 获取 token
      const userData = localStorage.getItem('userData');
      const { token = '' } = JSON.parse(userData || '{}');

      // 如果请求配置中提供了自定义前缀（比如 gatewayOverride），就使用它，否则默认 /gateway
      const gatewayPrefix = (config as any).gatewayOverride || '/gateway';
      // 删除自定义属性，防止被传递到服务器
      if ((config as any).gatewayOverride) {
        delete (config as any).gatewayOverride;
      }

      // 拼接 URL，并且合并 headers（注意如果 config.headers 中已有 token，也可以进行覆盖）
      return {
        ...config,
        url: `${gatewayPrefix}${config.url}`,
        headers: { ...config.headers, token },
      };
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response: AxiosResponse) => {
      // 拦截响应数据，进行个性化处理

      const {
        status,
        data: { status: code, errorMessage, msg },
        config: { method },
      } = response;

      try {
        if (status == 200) {
          // 网络请求成功

          if (method == 'post') {
            if (code == 200) {
              return response.data.data == null
                ? {
                    success: true,
                    data: true,
                  }
                : response.data;
            } else {
              notification.error({
                message: '',
                description: errorMessage || msg,
                placement: 'topRight',
                icon: <></>,
              });
              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({
                  message: '',
                  description: errorMessage || msg,
                  placement: 'topRight',
                  icon: <></>,
                });
                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 as keyof typeof iconEnum],
    children: item.children ? mappingIcon(item.children) : [],
  }));
  return mappingMenu;
};

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

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

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

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

const checkConfig = (props: any) => {
  return <IconFont type="icon-chengbenkuguanli" {...props} />;
};

//布局配置

export const layout = ({
  initialState,
  setInitialState,
}: {
  initialState: any;
  setInitialState: any;
}) => {
  const { isCollapsed } = initialState;
  const [openKeys, set_openKeys] = useState<string[]>([]);
  const [selectedKeys, set_selectedKeys] = useState<string[]>([]);

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

  return {
    menuHeaderRender: false,
    token: {
      sider: {
        colorMenuBackground: '#fff',
        colorTextMenuActive: '#3376FE',
        colorTextMenuSelected: '#3376FE',
        colorTextMenuTitle: '#17181A',
        colorTextMenu: '#17181A',
        //colorBgMenuItemHover:'##f0f2f5',
        colorBgMenuItemSelected: '#F2F6FF',
        colorTextMenuIcon: '#17181A',
        colorTextMenuIconActive: '#3376FE',
        colorTextMenuIconSelected: '#3376FE',
        // colorBgMenuItemCollapsedHover:'#f0f2f5',
        // //colorBgMenuItemCollapsedSelected:'blue'
      },
    },
    siderWidth: 200,
    menuProps: {
      openKeys: [...openKeys],
      selectedKeys: [...selectedKeys],
      onSelect: ({ selectedKeys }: { selectedKeys: string[] }) => {
        set_selectedKeys(selectedKeys);
        localStorage.setItem('selectedKeys', JSON.stringify(selectedKeys));
      },
      onOpenChange: (keys: string[]) => {
        set_openKeys([...keys]);
        localStorage.setItem('openKeys', JSON.stringify(keys));
      },
    },
    menu: {
      locale: false,
      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) {
            const selectedKeys = localStorage.getItem('selectedKeys');
            const openKeys = localStorage.getItem('openKeys');

            if (selectedKeys && openKeys) {
              const _selectedKeys = JSON.parse(selectedKeys);
              const _openKeys = JSON.parse(openKeys);
              set_openKeys(_openKeys);
              set_selectedKeys(_selectedKeys);
            } else {
              if (data[0].children && data[0].children.length > 0) {
                const childs = data[0].children;
                set_openKeys([data[0].key]);
                set_selectedKeys([childs[0].key]);
                localStorage.setItem('openKeys', JSON.stringify([data[0].key]));
                localStorage.setItem(
                  'selectedKeys',
                  JSON.stringify([childs[0].key]),
                );
                history.push(`${childs[0].path}`);
              } else {
                if (data[0]) {
                  set_openKeys([data[0].key]);
                  set_selectedKeys([data[0].key]);
                  localStorage.setItem(
                    'openKeys',
                    JSON.stringify([data[0].key]),
                  );
                  localStorage.setItem(
                    'selectedKeys',
                    JSON.stringify([data[0].key]),
                  );
                  history.push(`${data[0].path}`);
                }
              }
            }

            const getVFromTree = (data: any[], key: string) => {
              let result: any[] = [];
              function looper(data: any[], key: string) {
                data.forEach((t) => {
                  if (t[key] && t[key] != 0) {
                    //非一般页面
                    if (t[key] == 1 || t[key] == 2 || t[key] == 3) {
                      //网易有数页面
                      result.push({
                        contentType: t[key],
                        path: t['path'],
                        reportId: t['reportId'],
                        url: t['youshuUrl'],
                      });
                    }
                    if (t[key] == 5) {
                      result.push({
                        contentType: t[key],
                        path: t['path'],
                        reportId: t['reportId'],
                        url: t['softUrl'],
                      });
                    }
                  }
                  if (t.children && t.children.length > 0) {
                    looper(t.children, key);
                  }
                });
              }
              looper(data, key);
              return result;
            };

            const _menu = getVFromTree(data, 'contentType');

            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 == '/baseInfoMana') {
                  node.icon = <Icon component={fileIcon} />;
                }
                if (node.path == '/setting') {
                  node.icon = <Icon component={setting} />;
                }
                if (node.path == '/checkConfig') {
                  node.icon = (
                    <svg viewBox="0 0 1024 1024" width="1em" height="1em" fill="currentColor">
                      <path d="M781.970286 73.142857a36.571429 36.571429 0 0 1 32.694857 20.187429l182.857143 365.714285a36.571429 36.571429 0 0 1-32.694857 52.955429h-50.614858l83.382858 166.473143a36.571429 36.571429 0 0 1-32.768 52.955428H914.285714l83.236572 166.473143a36.571429 36.571429 0 0 1-32.694857 52.955429H59.172571a36.571429 36.571429 0 0 1-32.694857-52.955429L109.641143 731.428571h-50.468572a36.571429 36.571429 0 0 1-32.694857-52.955428L109.641143 512h-50.468572a36.571429 36.571429 0 0 1-32.694857-52.955429l182.857143-365.714285A36.571429 36.571429 0 0 1 242.029714 73.142857h539.940572z m50.395428 658.285714H191.414857l-73.069714 146.285715h787.236571l-73.216-146.285715z m0-219.428571H191.341714l-72.996571 146.285714h787.236571L832.365714 512z m-73.069714-365.714286H264.630857l-146.285714 292.571429h787.236571l-146.285714-292.571429z" />
                    </svg>
                  );
                }
              }
              if (node.children) {
                node.children.forEach((child: any) =>
                  addIconToPath(child, paths),
                );
              }
            }

            data.forEach((item: any) => {
              addIconToPath(item, ['/home', '/baseInfoMana', '/setting', '/checkConfig']);
            });

            return data;
          }
        }
      },
    },
    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,
    contentStyle: {
      // // border: '16px solid #F7F9FC',
      // //height: '94.5vh',  //以去除顶部导航高度
      // borderRadius: '22px',
      background: '#F7F9FC',
      height: 'calc(100vh - 48px)',
      // overflow:'scroll',
      // margin:'20px 20px'
    },
  };
};
