import { useEffect, useMemo, useState } from 'react'
import { HashRouter, Navigate, Outlet, Route, Routes, useLocation, useNavigate } from 'react-router-dom'
import { Alert, Result, Spin } from 'antd'
import { authApi, menuApi } from '@/lib/api'
import { buildFullMenus, findDefaultRoute, flattenMenus, isExternalMenu } from '@/lib/menu'
import { useAuthStore } from '@/store/auth'
import { LoginPage } from '@/features/auth/LoginPage'
import { AdminShell } from '@/features/layout/AdminShell'
import { DashboardPage } from '@/features/dashboard/DashboardPage'
import { ModuleLandingPage } from '@/features/discovery/ModuleLandingPage'
import { ProfilePage } from '@/features/person/ProfilePage'
import { ServerStatePage } from '@/features/server/ServerStatePage'
import { UserManagementPage } from '@/features/users/UserManagementPage'
import { RoleManagementPage } from '@/features/roles/RoleManagementPage'
import { MenuManagementPage } from '@/features/menus/MenuManagementPage'
import { ApiManagementPage } from '@/features/apis/ApiManagementPage'
import { DictionaryManagementPage } from '@/features/dictionaries/DictionaryManagementPage'
import { ParamsManagementPage } from '@/features/params/ParamsManagementPage'
import { LoginLogPage } from '@/features/logs/LoginLogPage'
import { OperationLogPage } from '@/features/logs/OperationLogPage'
import { SystemConfigPage } from '@/features/system/SystemConfigPage'
import { ApiTokenPage } from '@/features/tokens/ApiTokenPage'
import { ErrorLogPage } from '@/features/errors/ErrorLogPage'

type AppRoute = {
  path: string
  menuName: string
  element: React.ReactNode
}

const appRoutes: AppRoute[] = [
  { path: 'dashboard', menuName: 'dashboard', element: <DashboardPage /> },
  { path: 'about', menuName: 'about', element: <ModuleLandingPage moduleName="about" /> },
  { path: 'admin', menuName: 'superAdmin', element: <ModuleLandingPage moduleName="superAdmin" /> },
  { path: 'admin/authority', menuName: 'authority', element: <RoleManagementPage /> },
  { path: 'admin/menu', menuName: 'menu', element: <MenuManagementPage /> },
  { path: 'admin/api', menuName: 'api', element: <ApiManagementPage /> },
  { path: 'admin/user', menuName: 'user', element: <UserManagementPage /> },
  { path: 'admin/dictionary', menuName: 'dictionary', element: <DictionaryManagementPage /> },
  { path: 'admin/operation', menuName: 'operation', element: <OperationLogPage /> },
  { path: 'admin/sysParams', menuName: 'sysParams', element: <ParamsManagementPage /> },
  { path: 'admin/system', menuName: 'system', element: <SystemConfigPage /> },
  { path: 'admin/apiToken', menuName: 'apiToken', element: <ApiTokenPage /> },
  { path: 'admin/loginLog', menuName: 'loginLog', element: <LoginLogPage /> },
  { path: 'admin/sysVersion', menuName: 'sysVersion', element: <ModuleLandingPage moduleName="sysVersion" /> },
  { path: 'admin/sysError', menuName: 'sysError', element: <ErrorLogPage /> },
  { path: 'common', menuName: 'common', element: <ModuleLandingPage moduleName="common" /> },
  { path: 'common/upload', menuName: 'upload', element: <ModuleLandingPage moduleName="upload" /> },
  { path: 'example', menuName: 'example', element: <ModuleLandingPage moduleName="example" /> },
  { path: 'example/breakpoint', menuName: 'breakpoint', element: <ModuleLandingPage moduleName="breakpoint" /> },
  { path: 'example/customer', menuName: 'customer', element: <ModuleLandingPage moduleName="customer" /> },
  { path: 'systemTools', menuName: 'systemTools', element: <ModuleLandingPage moduleName="systemTools" /> },
  { path: 'systemTools/autoPkg', menuName: 'autoPkg', element: <ModuleLandingPage moduleName="autoPkg" /> },
  { path: 'systemTools/autoCode', menuName: 'autoCode', element: <ModuleLandingPage moduleName="autoCode" /> },
  { path: 'systemTools/autoCodeAdmin', menuName: 'autoCodeAdmin', element: <ModuleLandingPage moduleName="autoCodeAdmin" /> },
  { path: 'systemTools/formCreate', menuName: 'formCreate', element: <ModuleLandingPage moduleName="formCreate" /> },
  { path: 'systemTools/aiWorkflow', menuName: 'aiWorkflow', element: <ModuleLandingPage moduleName="aiWorkflow" /> },
  { path: 'systemTools/exportTemplate', menuName: 'exportTemplate', element: <ModuleLandingPage moduleName="exportTemplate" /> },
  { path: 'systemTools/mcpTest', menuName: 'mcpTest', element: <ModuleLandingPage moduleName="mcpTest" /> },
  { path: 'systemTools/mcpTool', menuName: 'mcpTool', element: <ModuleLandingPage moduleName="mcpTool" /> },
  { path: 'systemTools/skills', menuName: 'skills', element: <ModuleLandingPage moduleName="skills" /> },
  { path: 'systemTools/picture', menuName: 'picture', element: <ModuleLandingPage moduleName="picture" /> },
  { path: 'systemTools/autoCodeEdit/:id', menuName: 'autoCodeEdit', element: <ModuleLandingPage moduleName="autoCodeEdit" /> },
  { path: 'person', menuName: 'person', element: <ProfilePage /> },
  { path: 'state', menuName: 'state', element: <ServerStatePage /> },
]

function BootstrapGate() {
  const navigate = useNavigate()
  const location = useLocation()
  const token = useAuthStore((state) => state.token)
  const menus = useAuthStore((state) => state.menus)
  const setUser = useAuthStore((state) => state.setUser)
  const setMenus = useAuthStore((state) => state.setMenus)
  const clearSession = useAuthStore((state) => state.clearSession)
  const [loading, setLoading] = useState(true)
  const [loadError, setLoadError] = useState<string | null>(null)

  useEffect(() => {
    let ignore = false

    const bootstrap = async () => {
      if (!token) {
        navigate('/login', { replace: true, state: { redirectTo: location.pathname } })
        return
      }

      try {
        setLoading(true)
        const [userInfo, menuRes] = await Promise.all([authApi.getUserInfo(), menuApi.getMenu()])
        if (ignore) {
          return
        }

        setUser(userInfo.data.userInfo)
        setMenus(buildFullMenus(menuRes.data.menus))
        setLoadError(null)
      } catch (error) {
        if (ignore) {
          return
        }
        const message = error instanceof Error ? error.message : '会话恢复失败'
        clearSession()
        setLoadError(message)
        navigate('/login', { replace: true })
      } finally {
        if (!ignore) {
          setLoading(false)
        }
      }
    }

    bootstrap()

    return () => {
      ignore = true
    }
  }, [clearSession, location.pathname, navigate, setMenus, setUser, token])

  if (!token) {
    return null
  }

  if (loading && menus.length === 0) {
    return (
      <div className="fullscreen-status">
        <Spin size="large" />
        <span>正在恢复管理台会话...</span>
      </div>
    )
  }

  if (loadError) {
    return (
      <div className="fullscreen-status">
        <Alert type="error" message="会话恢复失败" description={loadError} showIcon />
      </div>
    )
  }

  return <Outlet />
}

function RouteGuard({ route }: { route: AppRoute }) {
  const menus = useAuthStore((state) => state.menus)
  const allowedPaths = useMemo(
    () =>
      new Set(
        flattenMenus(menus)
          .filter((item) => !isExternalMenu(item))
          .map((item) => item.fullPath),
      ),
    [menus],
  )

  if (!allowedPaths.has(`/${route.path}`)) {
    return (
      <Result
        status="403"
        title="当前角色无权访问此页面"
        subTitle="这个路由仍然存在于系统内，但当前角色没有对应菜单授权。"
      />
    )
  }

  return <>{route.element}</>
}

function LayoutFrame() {
  const menus = useAuthStore((state) => state.menus)
  const user = useAuthStore((state) => state.user)
  const defaultPath = findDefaultRoute(menus, user?.authority?.defaultRouter)

  return (
    <AdminShell>
      <Routes>
        <Route index element={<Navigate replace to={defaultPath || '/dashboard'} />} />
        {appRoutes.map((route) => (
          <Route key={route.path} path={route.path} element={<RouteGuard route={route} />} />
        ))}
        <Route path="*" element={<Result status="404" title="页面不存在" subTitle="请从左侧导航重新进入页面。" />} />
      </Routes>
    </AdminShell>
  )
}

export default function App() {
  return (
    <HashRouter>
      <Routes>
        <Route path="/login" element={<LoginPage />} />
        <Route element={<BootstrapGate />}>
          <Route path="/*" element={<LayoutFrame />} />
        </Route>
      </Routes>
    </HashRouter>
  )
}
