import { Layout, Menu, Space, Tag, Typography } from 'antd';
import type { ItemType } from 'antd/es/menu/interface';
import type { MainSidebarProps } from './types';

const { Sider } = Layout;
const { Text } = Typography;

export function MainSidebar({
  activeTopMenu,
  hasAccess,
  sidebarCollapsed,
  isMobileViewport,
  mobileInline = false,
  openKeys: controlledOpenKeys,
  apiMenuItems,
  docsMenuItems,
  planMenuItems,
  chatMenuItems,
  playMenuItems,
  selectedApiMenu,
  selectedDocsMenu,
  selectedPlanMenu,
  selectedChatMenu,
  selectedPlayMenu,
  introColor,
  introTag,
  introDescription,
  onOpenKeysChange,
  onSelectApiMenu,
  onSelectDocsMenu,
  onSelectPlanMenu,
  onSelectChatMenu,
  onSelectPlayMenu,
}: MainSidebarProps) {
  const handleMenuRouteSelection = (key: string, keyPath: string[]) => {
    if (keyPath.includes('docs-group')) {
      onSelectDocsMenu(key);
      return;
    }

    if (keyPath.includes('api-group')) {
      onSelectApiMenu(key as MainSidebarProps['selectedApiMenu']);
      return;
    }

    if (keyPath.includes('plan-group') || keyPath.includes('token-management-group') || keyPath.includes('server-group')) {
      onSelectPlanMenu(key as MainSidebarProps['selectedPlanMenu']);
      return;
    }

    if (keyPath.includes('chat-group') || keyPath.includes('app-log-group') || keyPath.includes('chat-manage-group')) {
      onSelectChatMenu(key as MainSidebarProps['selectedChatMenu']);
      return;
    }

    if (keyPath.includes('play-group') || keyPath.includes('play-layout-group')) {
      onSelectPlayMenu(key as MainSidebarProps['selectedPlayMenu']);
    }
  };

  const collectItemKeys = (items: ItemType[] | undefined): string[] =>
    (items ?? []).flatMap((item) => {
      if (!item || typeof item !== 'object' || !('key' in item)) {
        return [];
      }

      const itemKey = typeof item.key === 'string' ? item.key : '';
      const childKeys = 'children' in item ? collectItemKeys(item.children as ItemType[] | undefined) : [];
      return itemKey ? [itemKey, ...childKeys] : childKeys;
    });

  const effectiveTopMenu = !hasAccess ? 'docs' : activeTopMenu;
  const isDocsGroup = effectiveTopMenu === 'docs' || effectiveTopMenu === 'apis';
  const visibleOpenKeys = sidebarCollapsed ? [] : controlledOpenKeys;
  const selectedKeys =
    effectiveTopMenu === 'docs'
      ? [selectedDocsMenu]
      : effectiveTopMenu === 'apis'
        ? [selectedApiMenu]
        : effectiveTopMenu === 'plans'
          ? [selectedPlanMenu]
          : effectiveTopMenu === 'play'
            ? [selectedPlayMenu]
            : [selectedChatMenu];
  const sidebarItems =
    isDocsGroup
      ? !hasAccess
        ? [...(docsMenuItems ?? [])]
        : [...(docsMenuItems ?? []), ...(apiMenuItems ?? [])]
      : effectiveTopMenu === 'play'
        ? [...(playMenuItems ?? [])]
        : [...(chatMenuItems ?? []), ...(planMenuItems ?? [])];
  const rootKeys = sidebarItems.flatMap((item) =>
    item && typeof item === 'object' && 'key' in item && typeof item.key === 'string' ? [item.key] : [],
  );
  const childKeyMap = new Map(
    sidebarItems.flatMap((item) => {
      if (!item || typeof item !== 'object' || !('key' in item) || typeof item.key !== 'string') {
        return [];
      }

      return [[item.key, new Set(collectItemKeys('children' in item ? (item.children as ItemType[] | undefined) : undefined))]] as const;
    }),
  );
  const isMobileOverlay = isMobileViewport && !mobileInline;

  return (
    <Sider
      width={isMobileViewport ? '100%' : 260}
      collapsed={sidebarCollapsed}
      collapsedWidth={isMobileOverlay ? 0 : 72}
      className={
        isMobileOverlay ? 'app-sider app-sider--mobile' : mobileInline ? 'app-sider app-sider--mobile-inline' : 'app-sider'
      }
      theme="light"
    >
      <div className="app-sider__inner">
        <Space direction="vertical" size={8} className="app-sider__intro">
          <Tag color={introColor}>{introTag}</Tag>
          {!sidebarCollapsed ? (
            <Text type="secondary">{introDescription}</Text>
          ) : null}
        </Space>

        <Menu
          mode="inline"
          triggerSubMenuAction={isMobileViewport ? 'click' : 'hover'}
          inlineCollapsed={sidebarCollapsed}
          selectedKeys={selectedKeys}
          openKeys={visibleOpenKeys}
          items={sidebarItems}
          onOpenChange={(keys) => {
            const nextKeys = keys as string[];
            const rootOpenKeys = nextKeys.filter((key) => rootKeys.includes(key));

            if (rootOpenKeys.length <= 1) {
              onOpenKeysChange(nextKeys);
              return;
            }

            const activeRootKey =
              rootOpenKeys.find((key) => !visibleOpenKeys.includes(key)) ?? rootOpenKeys[rootOpenKeys.length - 1];
            const allowedChildKeys = childKeyMap.get(activeRootKey) ?? new Set<string>();
            onOpenKeysChange(nextKeys.filter((key) => key === activeRootKey || allowedChildKeys.has(key)));
          }}
          onClick={({ key, keyPath }) => {
            handleMenuRouteSelection(String(key), keyPath as string[]);
          }}
          onSelect={({ key, keyPath }) => {
            handleMenuRouteSelection(String(key), keyPath as string[]);
          }}
        />
      </div>
    </Sider>
  );
}
