/**
 * KRA - Combination Mode Layout
 * Combined top + side navigation layout
 */
import React, { useState, useEffect, useMemo } from 'react';
import { Layout, Menu } from 'antd';
import type { MenuProps } from 'antd';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
import { useModel, history, useLocation } from '@umijs/max';
import * as Icons from '@ant-design/icons';
import { useCollapsed, useConfig, useAsyncRouters, useTopMenu, useLeftMenu, useAppStore } from '@/models';

const { Sider } = Layout;

interface MenuItem {
  name: string;
  path: string;
  hidden?: boolean;
  meta?: {
    title: string;
    icon?: string;
    activeName?: string;
  };
  children?: MenuItem[];
  parameters?: Array<{ type: string; key: string; value: string }>;
}

// Get icon component by name
const getIcon = (iconName?: string): React.ReactNode => {
  if (!iconName) return null;
  const IconComponent = (Icons as any)[iconName] || (Icons as any)[`${iconName}Outlined`];
  return IconComponent ? <IconComponent /> : null;
};

// Convert menu data to Ant Design menu items (top level only for horizontal)
const convertToTopMenuItems = (menus: MenuItem[]): MenuProps['items'] => {
  return menus
    .filter((item) => !item.hidden)
    .map((item) => ({
      key: item.name,
      icon: getIcon(item.meta?.icon),
      label: item.meta?.title || item.name,
    }));
};

// Convert menu data to Ant Design menu items (with children for sidebar)
const convertToSideMenuItems = (menus: MenuItem[]): MenuProps['items'] => {
  return menus
    .filter((item) => !item.hidden)
    .map((item) => {
      const hasChildren = item.children && item.children.filter((c) => !c.hidden).length > 0;

      if (hasChildren) {
        return {
          key: item.name,
          icon: getIcon(item.meta?.icon),
          label: item.meta?.title || item.name,
          children: convertToSideMenuItems(item.children!),
        };
      }

      return {
        key: item.name,
        icon: getIcon(item.meta?.icon),
        label: item.meta?.title || item.name,
      };
    });
};

interface CombinationModeProps {
  /** Which part to render: 'head' for top menu, 'normal' for side menu */
  mode: 'head' | 'normal';
  /** Theme */
  theme?: 'light' | 'dark';
}

const CombinationMode: React.FC<CombinationModeProps> = ({ mode, theme = 'dark' }) => {
  const location = useLocation();
  const collapsed = useCollapsed();
  const config = useConfig();
  const asyncRouters = useAsyncRouters();
  const topMenu = useTopMenu();
  const leftMenu = useLeftMenu();
  const { setCollapsed, setLeftMenu, setTopActive } = useAppStore();
  const { routeMap, topActive } = useModel('router');

  const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
  const [openKeys, setOpenKeys] = useState<string[]>([]);

  // Get top menu items
  const topMenuItems = useMemo(() => {
    if (!topMenu?.length) {
      const rootMenu = asyncRouters?.[0];
      if (!rootMenu?.children) return [];
      return convertToTopMenuItems(rootMenu.children);
    }
    return convertToTopMenuItems(topMenu);
  }, [topMenu, asyncRouters]);

  // Get side menu items
  const sideMenuItems = useMemo(() => {
    if (!leftMenu?.length) return [];
    return convertToSideMenuItems(leftMenu);
  }, [leftMenu]);

  // Find parent keys for a menu item
  const findParentKeys = (name: string, menus: MenuItem[], parents: string[] = []): string[] => {
    for (const menu of menus) {
      if (menu.name === name) {
        return parents;
      }
      if (menu.children) {
        const found = findParentKeys(name, menu.children, [...parents, menu.name]);
        if (found.length > 0 || menu.children.some((c) => c.name === name)) {
          return found.length > 0 ? found : [...parents, menu.name];
        }
      }
    }
    return [];
  };

  // Update selected keys based on current route
  useEffect(() => {
    const pathname = location.pathname;
    const findMenuByPath = (menus: MenuItem[]): MenuItem | null => {
      for (const menu of menus) {
        if (menu.path === pathname || `/${menu.path}` === pathname) {
          return menu;
        }
        if (menu.children) {
          const found = findMenuByPath(menu.children);
          if (found) return found;
        }
      }
      return null;
    };

    if (leftMenu?.length) {
      const currentMenu = findMenuByPath(leftMenu);
      if (currentMenu) {
        setSelectedKeys([currentMenu.name]);
        const parentKeys = findParentKeys(currentMenu.name, leftMenu);
        if (parentKeys.length > 0 && !collapsed) {
          setOpenKeys(parentKeys);
        }
      }
    }
  }, [location.pathname, leftMenu, collapsed]);

  // Handle top menu click
  const handleTopMenuClick: MenuProps['onClick'] = ({ key }) => {
    setTopActive?.(key);
    
    // Find the menu item and set left menu
    const rootMenu = asyncRouters?.[0];
    const topMenuItem = rootMenu?.children?.find((item: MenuItem) => item.name === key);
    
    if (topMenuItem?.children?.length) {
      setLeftMenu?.(topMenuItem.children);
      // Navigate to first visible child
      const firstChild = topMenuItem.children.find((c: MenuItem) => !c.hidden);
      if (firstChild) {
        navigateToMenu(firstChild.name);
      }
    } else {
      setLeftMenu?.([]);
      navigateToMenu(key);
    }
  };

  // Handle side menu click
  const handleSideMenuClick: MenuProps['onClick'] = ({ key }) => {
    navigateToMenu(key);
  };

  // Navigate to menu
  const navigateToMenu = (key: string) => {
    const menuItem = routeMap?.[key];
    if (!menuItem) {
      history.push(`/${key}`);
      return;
    }

    if (key.startsWith('http://') || key.startsWith('https://')) {
      window.open(key, '_blank');
      return;
    }

    const query: Record<string, string> = {};
    const params: Record<string, string> = {};
    menuItem.parameters?.forEach((param: any) => {
      if (param.type === 'query') {
        query[param.key] = param.value;
      } else {
        params[param.key] = param.value;
      }
    });

    history.push({
      pathname: menuItem.path?.startsWith('/') ? menuItem.path : `/${menuItem.path}`,
      query,
    });
  };

  const handleOpenChange = (keys: string[]) => {
    setOpenKeys(keys);
  };

  const toggleCollapse = () => {
    setCollapsed(!collapsed);
  };

  const siderWidth = config?.sideWidth || 256;
  const siderCollapsedWidth = config?.sideCollapsedWidth || 80;

  // Render top menu (horizontal)
  if (mode === 'head') {
    return (
      <div
        style={{
          flex: 1,
          overflow: 'auto',
          display: 'flex',
          alignItems: 'center',
        }}
      >
        <Menu
          theme={theme === 'dark' ? 'dark' : 'light'}
          mode="horizontal"
          selectedKeys={topActive ? [topActive] : []}
          onClick={handleTopMenuClick}
          items={topMenuItems}
          style={{
            flex: 1,
            border: 'none',
            backgroundColor: 'transparent',
            lineHeight: '62px',
          }}
        />
      </div>
    );
  }

  // Render side menu (vertical)
  return (
    <Sider
      collapsible
      collapsed={collapsed}
      width={siderWidth}
      collapsedWidth={siderCollapsedWidth}
      theme={theme}
      trigger={null}
      style={{
        overflow: 'auto',
        height: '100%',
        position: 'relative',
      }}
    >
      <Menu
        theme={theme}
        mode="inline"
        selectedKeys={selectedKeys}
        openKeys={collapsed ? [] : openKeys}
        onOpenChange={handleOpenChange}
        onClick={handleSideMenuClick}
        items={sideMenuItems}
        style={{ borderRight: 0, height: 'calc(100% - 48px)' }}
      />

      {/* Collapse Toggle Button */}
      <div
        onClick={toggleCollapse}
        style={{
          position: 'absolute',
          bottom: 16,
          left: '50%',
          transform: 'translateX(-50%)',
          width: 32,
          height: 32,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: theme === 'dark' ? 'rgba(255,255,255,0.1)' : '#f5f5f5',
          borderRadius: 4,
          cursor: 'pointer',
          color: theme === 'dark' ? '#fff' : '#333',
        }}
      >
        {collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
      </div>
    </Sider>
  );
};

export default CombinationMode;
