import { useMemo } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import { Avatar, Button, Dropdown, Menu, Select, Space, Typography, message } from 'antd'
import type { ItemType } from 'antd/es/menu/interface'
import {
  ApiOutlined,
  AppstoreOutlined,
  BookOutlined,
  CodeOutlined,
  DashboardOutlined,
  LockOutlined,
  PartitionOutlined,
  SettingOutlined,
  UserOutlined,
} from '@ant-design/icons'
import { authApi, menuApi } from '@/lib/api'
import { buildFullMenus, findDefaultRoute, flattenMenus, isExternalMenu } from '@/lib/menu'
import { useAuthStore } from '@/store/auth'
import type { AppMenu } from '@/types/system'

const iconMap: Record<string, React.ReactNode> = {
  dashboard: <DashboardOutlined />,
  authority: <LockOutlined />,
  menu: <PartitionOutlined />,
  api: <ApiOutlined />,
  user: <UserOutlined />,
  dictionary: <BookOutlined />,
  sysParams: <SettingOutlined />,
  system: <SettingOutlined />,
  apiToken: <LockOutlined />,
  loginLog: <AppstoreOutlined />,
  systemTools: <CodeOutlined />,
  common: <BookOutlined />,
}

function buildMenuItems(menus: AppMenu[]): ItemType[] {
  return menus
    .filter((menu) => !menu.hidden)
    .map((menu) => {
      const icon = iconMap[menu.name] || <AppstoreOutlined />

      if (menu.children?.length) {
        return {
          key: menu.fullPathKey || menu.name,
          icon,
          label: menu.meta.title,
          children: buildMenuItems(menu.children),
        } satisfies ItemType
      }

      return {
        key: menu.fullPathKey || menu.name,
        icon,
        label: menu.meta.title,
      } satisfies ItemType
    })
}

type Props = {
  children: React.ReactNode
}

export function AdminShell({ children }: Props) {
  const navigate = useNavigate()
  const location = useLocation()
  const user = useAuthStore((state) => state.user)
  const menus = useAuthStore((state) => state.menus)
  const clearSession = useAuthStore((state) => state.clearSession)
  const setUser = useAuthStore((state) => state.setUser)
  const setMenus = useAuthStore((state) => state.setMenus)
  const selectedKey = location.pathname.replace(/^\//, '')

  const breadcrumb = useMemo(() => {
    const target = flattenMenus(menus).find((menu) => menu.fullPath === location.pathname)
    if (!target) {
      return []
    }

    const chain: string[] = []
    if (target.parentName) {
      const parent = flattenMenus(menus).find((menu) => menu.name === target.parentName)
      if (parent) {
        chain.push(parent.meta.title)
      }
    }
    chain.push(target.meta.title)
    return chain
  }, [location.pathname, menus])

  const menuItems = useMemo(() => buildMenuItems(menus), [menus])

  const handleMenuClick = ({ key }: { key: string }) => {
    const target = flattenMenus(menus).find((menu) => menu.fullPathKey === key)
    if (!target) {
      return
    }

    if (isExternalMenu(target)) {
      window.open(target.path, '_blank', 'noopener,noreferrer')
      return
    }

    navigate(target.fullPath)
  }

  const handleRoleSwitch = async (value: number) => {
    try {
      await authApi.changeAuthority(value)
      const [userInfo, menuRes] = await Promise.all([authApi.getUserInfo(), menuApi.getMenu()])
      const mappedMenus = buildFullMenus(menuRes.data.menus)
      setUser(userInfo.data.userInfo)
      setMenus(mappedMenus)
      message.success('角色切换成功')
      navigate(findDefaultRoute(mappedMenus, userInfo.data.userInfo.authority?.defaultRouter) || '/dashboard')
    } catch {
      message.error('角色切换失败')
    }
  }

  const handleLogout = async () => {
    try {
      await authApi.logout()
    } catch {
      // 忽略退出失败，统一清会话。
    } finally {
      clearSession()
      navigate('/login', { replace: true })
    }
  }

  return (
    <div className="admin-shell">
      <aside className="admin-sidebar">
        <div className="admin-brand">
          <Typography.Text style={{ color: 'rgba(255,255,255,0.65)' }}>React Admin</Typography.Text>
          <Typography.Title level={3} style={{ color: 'rgba(255,255,255,0.96)', margin: '8px 0 6px' }}>
            RMK Control Deck
          </Typography.Title>
          <Typography.Paragraph style={{ color: 'rgba(255,255,255,0.72)', marginBottom: 0 }}>
            基于现有 Gin 后端协议构建的新管理台。
          </Typography.Paragraph>
        </div>
        <Menu
          mode="inline"
          theme="dark"
          selectedKeys={[selectedKey]}
          items={menuItems}
          onClick={handleMenuClick}
          style={{ background: 'transparent', borderInlineEnd: 'none' }}
        />
      </aside>
      <main className="admin-main">
        <div className="page-stack">
          <div className="glass-panel page-panel" style={{ padding: 20 }}>
            <div className="section-heading" style={{ marginBottom: 4 }}>
              <div>
                <Typography.Text className="text-muted">
                  {breadcrumb.length ? breadcrumb.join(' / ') : '后台总览'}
                </Typography.Text>
                <Typography.Title level={3} style={{ margin: '8px 0 0' }}>
                  {breadcrumb.at(-1) || '管理后台'}
                </Typography.Title>
              </div>
              <Space size="middle" wrap>
                {user?.authorities?.length ? (
                  <Select
                    value={user.authority?.authorityId}
                    options={user.authorities.map((item) => ({
                      label: `${item.authorityName} (${item.authorityId})`,
                      value: item.authorityId,
                    }))}
                    style={{ minWidth: 220 }}
                    onChange={handleRoleSwitch}
                  />
                ) : null}
                <Dropdown
                  menu={{
                    items: [
                      {
                        key: 'profile',
                        label: '个人中心',
                        onClick: () => navigate('/person'),
                      },
                      {
                        key: 'logout',
                        label: '退出登录',
                        danger: true,
                        onClick: handleLogout,
                      },
                    ],
                  }}
                >
                  <Button type="text" style={{ height: 'auto', padding: 0 }}>
                    <Space>
                      <Avatar src={user?.headerImg} icon={<UserOutlined />} />
                      <span>{user?.nickName || user?.userName || '未登录'}</span>
                    </Space>
                  </Button>
                </Dropdown>
              </Space>
            </div>
          </div>
          {children}
        </div>
      </main>
    </div>
  )
}
