import React, {
  useMemo,
  useEffect,
  useRef,
  useCallback,
  type CSSProperties,
} from 'react';

import { useThemedLayoutContext } from '@refinedev/antd';
import {
  type ITreeMenu,
  pickNotDeprecated,
  useLink,
  useMenu,
  useNavigation,
  useGo,
} from '@refinedev/core';
import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';

import {
  BarsOutlined,
  LeftOutlined,
  RightOutlined,
  UnorderedListOutlined,
} from '@ant-design/icons';
import {
  Button,
  Drawer,
  Grid,
  Layout,
  Menu,
  theme,
  type MenuProps,
} from 'antd';
import { Title } from './title';
import { agentAttrs } from 'components/agentPanel/agentAttributes';

const drawerButtonStyles: CSSProperties = {
  borderTopLeftRadius: 0,
  borderBottomLeftRadius: 0,
  position: 'fixed',
  top: 64,
  zIndex: 1001,
};

let reRouteNum = 0;

const { SubMenu } = Menu;
const { useToken } = theme;

const getParentKeysFromMenuTree = (
  items: ITreeMenu[],
  targetKey: string,
  parentKeys: string[] = [],
): string[] | null => {
  for (const item of items) {
    const currentKey = item.key || '';

    if (currentKey === targetKey) {
      return parentKeys;
    }

    if (item.children && item.children.length > 0) {
      const found = getParentKeysFromMenuTree(item.children, targetKey, [
        ...parentKeys,
        currentKey,
      ]);
      if (found) {
        return found;
      }
    }
  }
  return null;
};

const getMenuLabel = (
  name: string,
  meta: Record<string, any>,
  locale: string,
): string => {
  const isZh = locale === 'zh_CN' || locale === 'zh';
  if (isZh && meta?.zhLabel) return meta.zhLabel;
  if (!isZh && meta?.enLabel) return meta.enLabel;
  return meta?.label || name;
};

export const Sider: React.FC = () => {
  const { token } = useToken();
  const { menuItems, selectedKey, defaultOpenKeys } = useMenu();
  const { pathname: currentPathname } = useLocation();
  const { t, i18n } = useTranslation();
  const currentLocale = i18n.language;

  const [openKeys, setOpenKeys] = React.useState<string[]>(defaultOpenKeys);

  const lastSelectedKeyRef = useRef<string | undefined>(undefined);

  useEffect(() => {
    if (
      selectedKey &&
      selectedKey !== lastSelectedKeyRef.current &&
      menuItems.length > 0
    ) {
      lastSelectedKeyRef.current = selectedKey;

      const parentKeys = getParentKeysFromMenuTree(menuItems, selectedKey);

      if (parentKeys !== null) {
        setOpenKeys(parentKeys);
      }
    }
  }, [selectedKey, menuItems]);

  const {
    siderCollapsed,
    setSiderCollapsed,
    mobileSiderOpen,
    setMobileSiderOpen,
  } = useThemedLayoutContext();

  const Link = useLink();
  const go = useGo();

  const breakpoint = Grid.useBreakpoint();
  const { listUrl } = useNavigation();

  const isMobile =
    typeof breakpoint.lg === 'undefined' ? false : !breakpoint.lg;

  const renderTreeView = useCallback(
    (tree: ITreeMenu[], currentSelectedKey?: string): MenuProps['items'] => {
      return tree
        .map((item: ITreeMenu) => {
          const { key, name, children, meta = {}, list } = item;
          const { icon, parent: parentName } = meta;

          const route = typeof list === 'string' ? list : listUrl(name);

          if (children.length > 0) {
            return {
              key: item.key || Math.random().toString(),
              label: (
                <span style={{ fontWeight: 600 }}>
                  {getMenuLabel(name, meta, currentLocale)}
                </span>
              ),
              icon: icon ?? <UnorderedListOutlined />,
              children: renderTreeView(children, currentSelectedKey),
            };
          }

          const menuItemKey = item.key || Math.random().toString();
          const isSelected = menuItemKey === currentSelectedKey;
          const isRoute = !(
            pickNotDeprecated(meta?.parent, meta?.parent, parentName) !==
              undefined && children.length === 0
          );

          return {
            key: menuItemKey,
            label: (
              <>
                <Link to={route ?? ''}>
                  {getMenuLabel(name, meta, currentLocale)}
                </Link>
                {!siderCollapsed && isSelected && (
                  <div className="ant-menu-tree-arrow" />
                )}
              </>
            ),
            icon: icon ?? (isRoute && <UnorderedListOutlined />),
          };
        })
        .filter(Boolean);
    },
    [listUrl, Link, siderCollapsed, currentLocale],
  );

  const items = useMemo(() => {
    return renderTreeView(menuItems, selectedKey)?.filter(Boolean);
  }, [menuItems, selectedKey, renderTreeView]);

  // Auto-redirect to first available menu item if current selectedKey is not in the menu
  useEffect(() => {
    if (reRouteNum > 5) return;

    const isKeyInMenuItems = (
      menuItems: MenuProps['items'],
      key: string,
    ): boolean => {
      if (!menuItems) return false;
      for (const item of menuItems) {
        if (!item) continue;
        if (item.key === key) return true;
        if ('children' in item && item.children) {
          if (isKeyInMenuItems(item.children as MenuProps['items'], key))
            return true;
        }
      }
      return false;
    };

    // If selectedKey is in the menu, no need to redirect
    if (selectedKey && isKeyInMenuItems(items, selectedKey)) {
      return;
    }

    // Skip auto-redirect for CRUD detail pages (edit/show/create)
    // These pages are not in the menu but are valid navigation targets.
    // Also skip auto-generated /admin/data-mngt/* CRUD list pages —
    // some of them are intentionally hidden from the sidebar via
    // meta.hide but remain reachable through buttons on other pages.
    // Use the live router pathname (not Refine's selectedKey, which
    // collapses to an ancestor when the resource is hidden).
    if (
      currentPathname &&
      (currentPathname.includes('/edit/') ||
        currentPathname.includes('/show/') ||
        currentPathname.endsWith('/create') ||
        currentPathname.includes('/data-mngt/'))
    ) {
      return;
    }

    const timer = setTimeout(() => {
      reRouteNum++;

      const firstKey = items?.[0]?.key;
      if (firstKey && firstKey !== '/dashboard') {
        setOpenKeys([String(firstKey)]);
        const firstItem = items?.find((item) => item?.key === firstKey) as any;
        if (firstItem?.children?.length > 0) {
          let childItem = firstItem?.children?.find(
            (item: any) => selectedKey.indexOf(item?.key) !== -1,
          );
          if (!childItem) {
            childItem = firstItem?.children?.[0];
          }
          const childKey = childItem?.key;
          if (childItem?.children?.length > 0) {
            setOpenKeys([String(firstKey), String(childKey)]);
            const grandsonItem = childItem?.children?.find(
              (item: any) => selectedKey.indexOf(item?.key) !== -1,
            );
            const grandsonKey =
              grandsonItem?.key || firstItem?.children?.[0]?.children?.[0]?.key;
            go({ to: grandsonKey, type: 'replace' });
          } else {
            go({ to: childKey, type: 'replace' });
          }
        } else {
          go({ to: String(firstKey), type: 'replace' });
        }
      }
    }, 300);

    return () => clearTimeout(timer);
  }, [items, selectedKey, currentPathname, go]);

  const handleOpenChange = useCallback(
    (keys: string[]) => {
      const latestOpenKey = keys.find((key) => !openKeys.includes(key));

      if (latestOpenKey) {
        const parentKeys =
          getParentKeysFromMenuTree(menuItems, latestOpenKey) || [];
        setOpenKeys([...parentKeys, latestOpenKey]);
      } else {
        setOpenKeys(keys);
      }
    },
    [openKeys, menuItems],
  );

  const handleMenuClick = useCallback(
    ({ key }: { key: string }) => {
      const clickedItem = menuItems.find((item) => item.key === key);
      if (clickedItem && clickedItem.children.length === 0) {
        setOpenKeys([]);
      }
      setMobileSiderOpen(false);
    },
    [menuItems, setMobileSiderOpen],
  );

  const renderMenu = useCallback(() => {
    return (
      <Menu
        selectedKeys={selectedKey ? [selectedKey] : []}
        defaultOpenKeys={defaultOpenKeys}
        openKeys={openKeys}
        onOpenChange={handleOpenChange}
        mode="inline"
        items={items}
        style={{
          paddingTop: '8px',
          border: 'none',
          overflow: 'auto',
          height: 'calc(100% - 72px)',
          background: 'transparent',
        }}
        onClick={handleMenuClick}
      ></Menu>
    );
  }, [
    selectedKey,
    defaultOpenKeys,
    openKeys,
    handleOpenChange,
    items,
    handleMenuClick,
  ]);

  const renderDrawerSider = () => {
    return (
      <>
        <Drawer
          open={mobileSiderOpen}
          onClose={() => setMobileSiderOpen(false)}
          placement="left"
          closable={false}
          width={256}
          styles={{
            body: {
              padding: 0,
            },
          }}
          maskClosable={true}
        >
          <Layout>
            <Layout.Sider
              width={500}
              style={{
                height: '100vh',
                backgroundColor: token.colorBgContainer,
                borderRight: `1px solid ${token.colorBorderBg}`,
              }}
            >
              <div
                {...agentAttrs({ type: 'app-title' })}
                style={{
                  width: '256px',
                  padding: '0 16px',
                  display: 'flex',
                  justifyContent: 'flex-start',
                  alignItems: 'center',
                  height: '64px',
                  backgroundColor: token.colorBgElevated,
                  borderBottom: 'none',
                }}
              >
                <Title collapsed={false} />
              </div>
              {renderMenu()}
            </Layout.Sider>
          </Layout>
        </Drawer>
        <Button
          style={drawerButtonStyles}
          size="large"
          onClick={() => setMobileSiderOpen(true)}
          icon={<BarsOutlined />}
        />
      </>
    );
  };

  if (isMobile) {
    return renderDrawerSider();
  }

  const siderStyles: React.CSSProperties = {
    backgroundColor: token.colorBgContainer,
    borderRight: `1px solid ${token.colorBorderBg}`,
    position: 'sticky',
    top: 0,
    left: 0,
    height: '100vh',
    zIndex: 999,
  };

  return (
    <>
      <Layout.Sider
        style={siderStyles}
        width={256}
        collapsible
        collapsed={siderCollapsed}
        onCollapse={(collapsed, type) => {
          if (type === 'clickTrigger') {
            setSiderCollapsed(collapsed);
          }
        }}
        collapsedWidth={80}
        breakpoint="lg"
        trigger={
          <Button
            type="text"
            style={{
              borderRadius: 0,
              height: '100%',
              width: '100%',
              backgroundColor: token.colorBgElevated,
              borderRight: `1px solid ${token.colorBorderBg}`,
            }}
          >
            {siderCollapsed ? (
              <RightOutlined
                style={{
                  color: token.colorPrimary,
                }}
              />
            ) : (
              <LeftOutlined
                style={{
                  color: token.colorPrimary,
                }}
              />
            )}
          </Button>
        }
      >
        <div
          {...agentAttrs({ type: 'app-title' })}
          style={{
            width: siderCollapsed ? '80px' : '256px',
            padding: siderCollapsed ? '0' : '0 16px',
            display: 'flex',
            justifyContent: siderCollapsed ? 'center' : 'flex-start',
            alignItems: 'center',
            height: '64px',
            backgroundColor: token.colorBgElevated,
            fontSize: '14px',
          }}
        >
          <Title collapsed={siderCollapsed} />
        </div>
        {renderMenu()}
      </Layout.Sider>
    </>
  );
};
