/*
 * @Author: code4eat awesomedema@gmail.com
 * @Date: 2022-12-14 14:14:32
 * @LastEditors: code4eat awesomedema@gmail.com
 * @LastEditTime: 2024-07-17 14:56:56
 * @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, 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 { getPlatformMenu } from '@/services/auth';
import { useEffect, useState } from 'react';


import './utils/zhongtaiC'

import ResizableContainer from './components/ResizableContainer/index';




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[]
}> {

  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) => {
      // 拦截请求配置，进行个性化处理。
      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: { success, status: code, errorMessage, msg, data: respData }, 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({
                top:72,
                message: '提示',
                description: errorMessage || msg,
                placement: 'topRight',
                icon:<IconFont type="icon-jinggaotishi"  />,
                style:{padding:16,margin:0,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,margin:0,borderRadius:8}
                })
                return false;
              }
            }

          }

        } else {
          return false
        }

      } catch (error) {
        console.log({ error });
      }
    }
  ]
};




export function patchClientRoutes({ routes }: { routes: any }) {

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

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

      //console.log({paths});

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



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 = (params: any) => {
  return <IconFont type='icon-jixiaoguanli' />
};

const setting = (params: any) => {
  return <IconFont type='icon-xitongshezhi' />
};

const secondaryDistribute = (params: any) => {
  return <IconFont type='icon-ercifenpei' />
};

const reportCheck = (params: any) => {
  return <IconFont type='icon-baobiaochaxun' />
};

const crosstabReport = (params: any) => {
  return <IconFont type='icon-baobiaochaxun' />
};

//布局配置

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

  const { isCollapsed } = initialState;


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


  return {
    disableMobile: true,
    menuRender: (props: any) => {


      const { location } = props;
      const [menu, set_menu] = useState<any[]>([]);

      const [slectedKey, set_slectedKey] = useState<string[]>([]);
      const [openKeys, set_openKeys] = useState<string[]>([]);

      // const currentSelectedItem = findItemByKey(menuData,location.pathname,'path');

      const menuClickHandle = (info: any) => {
        const foundItem = findItemByKey(menu, info.key, 'key');
        // console.log({foundItem,info});
        if (foundItem) {
          set_slectedKey([`${info.key}`]);
          history.push(foundItem.path);

        }

      }

      const onOpenChangeHandle = (openKeys: string[]) => {
        set_openKeys(openKeys);
      }

      const getMenu = async () => {
        const userData = localStorage.getItem('userData');
        const currentSelectedTab = localStorage.getItem('currentSelectedTab');
        if (currentSelectedTab) {
          const { menuId, path } = JSON.parse(currentSelectedTab);
          const systemId = menuId;
          const data: any[] = await getPlatformMenu(systemId);
          if (data) {
            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) }));

            //return mappingIcon(data);



            function addIconToPath(node: any, paths: string[]) {
              if (paths.includes(node.path)) {
                if (node.path == '/home') {
                  node.icon = <Icon component={imgNode} />;
                }
                if (node.path == '/budgetMana') {
                  node.icon = <Icon component={fileIcon} />;
                }
                if (node.path == '/setting') {
                  node.icon = <Icon component={setting} />;
                }
                if (node.path == '/reportCheck') {
                  node.icon = <Icon component={setting} />;
                }
                if (node.path == '/secondaryDistribute') {
                  node.icon = <Icon component={secondaryDistribute} />;
                }
                if (node.path == '/reportCheck') {
                  node.icon = <Icon component={reportCheck} />;
                }
                if (node.path == '/crosstabReport') {
                  node.icon = <Icon component={reportCheck} />;
                }
              }
              if (node.children) {
                node.children.forEach((child: any) => addIconToPath(child, paths));
              }

              // node.icon = <FolderOutlined />;
              // if (node.children) {
              //   node.children.forEach((child: any) => addIconToPath(child, paths));
              // }
            }

            data.forEach((item: any) => {
              addIconToPath(item, ['/home', '/budgetMana', '/setting', '/reportCheck', '/secondaryDistribute', '/crosstabReport']);
            });

            const { newTree, firstLeafNode, firstLeafNodePath } = transformTree(data);
            // set_openKeys(firstLeafNodePath.map(a => `${a.key}`));
            // set_slectedKey([`${firstLeafNode.key}`]);
            set_menu(newTree);

          }
        }
      }

      useEffect(() => {

        const foundItem = findItemByKey(menu, location.pathname, 'path');

        if (foundItem) {
          set_slectedKey(foundItem.key);

        }

      }, [menu]);

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

      return (
        <ResizableContainer width={isCollapsed?64:200} minWidth={0} maxWidth={600} height={'calc(100vh - 58px)'}>
          <div style={{ height: '100%', background: '#fff', position: 'relative' }}>
            <div className='menuWrapper' style={{height:'calc(100% - 40px)',overflowY: 'scroll',overflowX:'hidden'}}>
              <Menu
                
                onClick={menuClickHandle}
                onOpenChange={onOpenChangeHandle}
                style={{ width: '100%' }}
                openKeys={openKeys}
                selectedKeys={slectedKey}
                mode="inline"
                items={menu}
                inlineCollapsed={isCollapsed}
              />
            </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>
      );
    },
    collapsed: isCollapsed,
    contentStyle: {
      border: '16px solid #F7F9FC',
      borderRight: '10px solid #F7F9FC',
      //height: '94.5vh',  //以去除顶部导航高度
      borderRadius: '22px',
      background: '#F7F9FC',
      height: 'calc(100vh - 48px)'
      // overflow:'scroll',
      // margin:'20px 20px'
    },
  };
};
