/**
 * KRA - App Configuration
 * 应用运行时配置
 * 参考 GVA 的 permission.js 和 router store 实现动态路由
 */
import { AvatarDropdown, AvatarName, Footer } from '@/components';
import CommandMenu from '@/components/CommandMenu';
import { getUserInfo } from '@/services/kratos/user';
import { asyncMenu } from '@/services/kratos/menu';
import { getToken } from '@/utils/auth';
import { asyncRouterHandle, BackendMenuItem } from '@/utils/dynamicRouter';
import {
  BulbOutlined,
  BulbFilled,
  ReloadOutlined,
  SettingOutlined,
  UserOutlined,
  QuestionCircleOutlined,
  SearchOutlined,
} from '@ant-design/icons';
import * as Icons from '@ant-design/icons';
import type { Settings as LayoutSettings, MenuDataItem } from '@ant-design/pro-components';
import { SettingDrawer } from '@ant-design/pro-components';
import type { RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
import { history } from '@umijs/max';
import { Tooltip } from 'antd';
import React, { useState } from 'react';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './requestErrorConfig';

const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';
const initPath = '/init';
const whiteList = [loginPath, initPath, '/error/403', '/error/404', '/error/500', '/scanUpload'];

// 图标映射函数
const iconMap: Record<string, React.ReactNode> = {};
Object.keys(Icons).forEach((key) => {
  if (key.endsWith('Outlined') || key.endsWith('Filled') || key.endsWith('TwoTone')) {
    const IconComponent = (Icons as any)[key];
    iconMap[key.toLowerCase().replace(/(outlined|filled|twotone)$/, '')] = <IconComponent />;
  }
});

// 自定义图标映射（GVA 使用的图标名称）
const customIconMap: Record<string, React.ReactNode> = {
  'odometer': <Icons.DashboardOutlined />,
  'user': <Icons.UserOutlined />,
  'avatar': <Icons.TeamOutlined />,
  'tickets': <Icons.MenuOutlined />,
  'platform': <Icons.ApiOutlined />,
  'coordinate': <Icons.UserOutlined />,
  'notebook': <Icons.BookOutlined />,
  'pie-chart': <Icons.PieChartOutlined />,
  'compass': <Icons.CompassOutlined />,
  'tools': <Icons.ToolOutlined />,
  'cpu': <Icons.CodeOutlined />,
  'magic-stick': <Icons.ThunderboltOutlined />,
  'operation': <Icons.SettingOutlined />,
  'folder': <Icons.FolderOutlined />,
  'reading': <Icons.FileTextOutlined />,
  'picture-filled': <Icons.PictureOutlined />,
  'magnet': <Icons.ApiOutlined />,
  'partly-cloudy': <Icons.CloudOutlined />,
  'server': <Icons.CloudServerOutlined />,
  'warn': <Icons.WarningOutlined />,
  'cherry': <Icons.AppstoreOutlined />,
  'shop': <Icons.ShopOutlined />,
  'box': <Icons.InboxOutlined />,
  'files': <Icons.FileOutlined />,
  'message': <Icons.MailOutlined />,
  'scaleToOriginal': <Icons.NotificationOutlined />,
  'upload': <Icons.UploadOutlined />,
  'upload-filled': <Icons.CloudUploadOutlined />,
  'management': <Icons.ExperimentOutlined />,
  'info-filled': <Icons.InfoCircleOutlined />,
  'cloudy': <Icons.CloudOutlined />,
  'setting': <Icons.SettingOutlined />,
  'customer-gva': <Icons.LinkOutlined />,
};

function getIcon(iconName?: string): React.ReactNode {
  if (!iconName) return undefined;
  // 先查自定义映射
  if (customIconMap[iconName]) return customIconMap[iconName];
  // 再查 antd 图标
  const key = iconName.toLowerCase().replace(/-/g, '');
  if (iconMap[key]) return iconMap[key];
  return undefined;
}

/**
 * 将后端菜单数据转换为 ProLayout 菜单格式
 */
function convertToMenuData(menus: BackendMenuItem[], parentPath: string = ''): MenuDataItem[] {
  return menus.map((menu) => {
    const path = menu.path.startsWith('/') || menu.path.startsWith('http') 
      ? menu.path 
      : `${parentPath}/${menu.path}`.replace(/\/+/g, '/');
    
    const menuItem: MenuDataItem = {
      path,
      name: menu.meta?.title || menu.name,
      icon: getIcon(menu.meta?.icon),
      hideInMenu: menu.hidden,
    };
    
    if (menu.children && menu.children.length > 0) {
      menuItem.children = convertToMenuData(menu.children, path);
    }
    
    return menuItem;
  });
}

/**
 * 获取初始状态
 * @see https://umijs.org/docs/api/runtime-config#getinitialstate
 */
export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>;
  currentUser?: API.CurrentUser;
  loading?: boolean;
  menus?: BackendMenuItem[];
  menuData?: MenuDataItem[];
  fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
  fetchMenus?: () => Promise<BackendMenuItem[]>;
}> {
  // 获取用户信息
  const fetchUserInfo = async (): Promise<API.CurrentUser | undefined> => {
    try {
      const token = getToken();
      if (!token) {
        return undefined;
      }
      const res = await getUserInfo();
      if (res.code === 0 && res.data?.userInfo) {
        const userInfo = res.data.userInfo;
        return {
          uuid: userInfo.uuid,
          userName: userInfo.userName,
          nickName: userInfo.nickName,
          name: userInfo.nickName || userInfo.userName,
          avatar: userInfo.headerImg,
          headerImg: userInfo.headerImg,
          authority: userInfo.authority,
          authorities: userInfo.authorities,
          buttons: res.data.buttons || [],
        };
      }
      return undefined;
    } catch (error) {
      console.error('获取用户信息失败:', error);
      return undefined;
    }
  };

  // 获取动态菜单 - 对应 GVA 的 SetAsyncRouter
  const fetchMenus = async (): Promise<BackendMenuItem[]> => {
    try {
      const token = getToken();
      if (!token) {
        return [];
      }
      const res = await asyncMenu();
      if (res.code === 0 && res.data?.menus) {
        return res.data.menus;
      }
      return [];
    } catch (error) {
      console.error('获取菜单失败:', error);
      return [];
    }
  };

  // 如果是白名单页面，不获取用户信息和菜单
  const { location } = history;
  if (whiteList.some((path) => location.pathname.startsWith(path))) {
    return {
      fetchUserInfo,
      fetchMenus,
      settings: defaultSettings as Partial<LayoutSettings>,
    };
  }

  // 获取用户信息和菜单
  const currentUser = await fetchUserInfo();
  if (!currentUser) {
    history.push(loginPath);
    return {
      fetchUserInfo,
      fetchMenus,
      settings: defaultSettings as Partial<LayoutSettings>,
    };
  }

  // 获取动态菜单
  const menus = await fetchMenus();
  const menuData = convertToMenuData(menus);

  return {
    fetchUserInfo,
    fetchMenus,
    currentUser,
    menus,
    menuData,
    settings: defaultSettings as Partial<LayoutSettings>,
  };
}

/**
 * ProLayout 配置
 * @see https://procomponents.ant.design/components/layout
 */
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  const handleRefresh = () => {
    window.location.reload();
  };

  const handleToggleTheme = () => {
    const newNavTheme = initialState?.settings?.navTheme === 'realDark' ? 'light' : 'realDark';
    setInitialState((preInitialState) => ({
      ...preInitialState,
      settings: {
        ...preInitialState?.settings,
        navTheme: newNavTheme,
      },
    }));
  };

  const handleOpenSetting = () => {
    const settingBtn = document.querySelector('.ant-pro-setting-drawer-handle');
    if (settingBtn) {
      (settingBtn as HTMLElement).click();
    }
  };

  const iconStyle: React.CSSProperties = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    width: 32,
    height: 32,
    borderRadius: '50%',
    border: '1px solid #d9d9d9',
    cursor: 'pointer',
  };

  return {
    ...initialState?.settings,

    // 使用后端返回的菜单数据
    menu: {
      locale: false, // 禁用国际化
      request: async () => {
        // 返回已获取的菜单数据
        return initialState?.menuData || [];
      },
    },

    actionsRender: () => {
      const isDarkTheme = initialState?.settings?.navTheme === 'realDark';
      return [
        <Tooltip title="帮助文档" key="doc">
          <a
            href="https://go-kratos.dev/"
            target="_blank"
            rel="noreferrer"
            style={{ ...iconStyle, color: 'inherit' }}
          >
            <QuestionCircleOutlined style={{ fontSize: 16 }} />
          </a>
        </Tooltip>,
        <Tooltip title="搜索 (Ctrl+K)" key="search">
          <span
            onClick={() => window.dispatchEvent(new CustomEvent('openCommandMenu'))}
            style={iconStyle}
          >
            <SearchOutlined style={{ fontSize: 16 }} />
          </span>
        </Tooltip>,
        <Tooltip title="系统设置" key="setting">
          <span onClick={handleOpenSetting} style={iconStyle}>
            <SettingOutlined style={{ fontSize: 16 }} />
          </span>
        </Tooltip>,
        <Tooltip title="刷新" key="refresh">
          <span onClick={handleRefresh} style={iconStyle}>
            <ReloadOutlined style={{ fontSize: 16 }} />
          </span>
        </Tooltip>,
        <Tooltip title="切换主题" key="theme">
          <span onClick={handleToggleTheme} style={iconStyle}>
            {isDarkTheme ? (
              <BulbFilled style={{ fontSize: 16, color: '#faad14' }} />
            ) : (
              <BulbOutlined style={{ fontSize: 16 }} />
            )}
          </span>
        </Tooltip>,
      ];
    },

    avatarProps: {
      src: initialState?.currentUser?.avatar || initialState?.currentUser?.headerImg || '/default-avatar.svg',
      title: <AvatarName />,
      icon: <UserOutlined />,
      render: (_, avatarChildren) => <AvatarDropdown menu>{avatarChildren}</AvatarDropdown>,
    },

    waterMarkProps: {
      content: initialState?.currentUser?.nickName || initialState?.currentUser?.userName,
    },

    footerRender: () => <Footer />,

    onPageChange: () => {
      const { location } = history;
      if (whiteList.some((path) => location.pathname.startsWith(path))) {
        return;
      }
      if (!initialState?.currentUser) {
        history.push(loginPath);
      }
    },

    menuHeaderRender: undefined,

    // 菜单项渲染 - 处理外部链接
    menuItemRender: (item, dom) => {
      if (item.path?.startsWith('http')) {
        return (
          <a href={item.path} target="_blank" rel="noopener noreferrer">
            {dom}
          </a>
        );
      }
      return (
        <a
          onClick={() => {
            if (item.path) {
              history.push(item.path);
            }
          }}
        >
          {dom}
        </a>
      );
    },

    unAccessible: (
      <div style={{ textAlign: 'center', padding: '100px 0' }}>
        <h1>403</h1>
        <p>抱歉，您没有权限访问此页面</p>
      </div>
    ),

    childrenRender: (children) => {
      return (
        <>
          {children}
          <CommandMenuWrapper />
          <SettingDrawer
            disableUrlParams
            enableDarkTheme
            settings={initialState?.settings}
            onSettingChange={(settings) => {
              setInitialState((preInitialState) => ({
                ...preInitialState,
                settings,
              }));
            }}
          />
        </>
      );
    },
  };
};

// CommandMenu包装组件
const CommandMenuWrapper: React.FC = () => {
  const [open, setOpen] = useState(false);

  React.useEffect(() => {
    const handleOpen = () => setOpen(true);
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.ctrlKey && e.key === 'k') {
        e.preventDefault();
        setOpen(true);
      }
    };
    window.addEventListener('openCommandMenu', handleOpen);
    window.addEventListener('keydown', handleKeyDown);
    return () => {
      window.removeEventListener('openCommandMenu', handleOpen);
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, []);

  return <CommandMenu open={open} onClose={() => setOpen(false)} />;
};

/**
 * 请求配置
 * @see https://umijs.org/docs/max/request#配置
 */
export const request: RequestConfig = {
  baseURL: isDev ? '/api' : '/api',
  timeout: 30000,
  ...errorConfig,
};
