import { Suspense, lazy } from 'react'
import { Spin } from 'antd'
import { HashRouter, Navigate, Outlet, Route, Routes, useLocation } from 'react-router'

import { getAdminRole, hasAdminSession } from '@/utils/admin-auth'
import AdminLayout from '@/layouts/AdminLayout'

const AdminDashboardPage = lazy(() => import('@/pages/admin/AdminDashboardPage'))
const AdminAuditLogsPage = lazy(() => import('@/pages/admin/AdminAuditLogsPage'))
const AdminLoginPage = lazy(() => import('@/pages/admin/AdminLoginPage'))
const AdminOrderDetailPage = lazy(() => import('@/pages/admin/AdminOrderDetailPage'))
const AdminOrdersPage = lazy(() => import('@/pages/admin/AdminOrdersPage'))
const AdminPlatformFulfillmentPage = lazy(
  () => import('@/pages/admin/platform/AdminPlatformFulfillmentPage'),
)
const AdminPlatformShopsPage = lazy(() => import('@/pages/admin/platform/AdminPlatformShopsPage'))
const AdminTaskDetailPage = lazy(() => import('@/pages/admin/AdminTaskDetailPage'))
const AdminTasksPage = lazy(() => import('@/pages/admin/AdminTasksPage'))
const AdminUsersPage = lazy(() => import('@/pages/admin/AdminUsersPage'))
const ClaimPage = lazy(() => import('@/pages/claim/ClaimPage'))
const NotFoundPage = lazy(() => import('@/pages/NotFoundPage'))

function RequireAdmin() {
  const location = useLocation()

  if (!hasAdminSession()) {
    return <Navigate to="/admin/login" replace state={{ from: location }} />
  }

  return <Outlet />
}

function RequireRole({ roles }: { roles: Array<'admin' | 'operator' | 'support'> }) {
  if (!roles.includes(getAdminRole())) {
    return <Navigate to="/admin/dashboard" replace />
  }

  return <Outlet />
}

function LoginRoute() {
  if (hasAdminSession()) {
    return <Navigate to="/admin/dashboard" replace />
  }

  return <AdminLoginPage />
}

export default function App() {
  return (
    <HashRouter>
      <Suspense fallback={<RouteLoading />}>
        <Routes>
          <Route path="/" element={<Navigate to="/admin/dashboard" replace />} />
          <Route path="/admin/login" element={<LoginRoute />} />
          <Route element={<RequireAdmin />}>
            <Route path="/admin" element={<AdminLayout />}>
              <Route index element={<Navigate to="/admin/dashboard" replace />} />
              <Route path="dashboard" element={<AdminDashboardPage />} />
              <Route path="orders" element={<AdminOrdersPage />} />
              <Route path="orders/:orderId" element={<AdminOrderDetailPage />} />
              <Route path="tasks" element={<AdminTasksPage />} />
              <Route path="tasks/:taskId" element={<AdminTaskDetailPage />} />
              <Route element={<RequireRole roles={['admin']} />}>
                <Route path="users" element={<AdminUsersPage />} />
                <Route path="platform-shops" element={<AdminPlatformShopsPage />} />
                <Route path="platform-fulfillment" element={<AdminPlatformFulfillmentPage />} />
                <Route path="audit-logs" element={<AdminAuditLogsPage />} />
              </Route>
            </Route>
          </Route>
          <Route path="/claim/:token" element={<ClaimPage />} />
          <Route path="*" element={<NotFoundPage />} />
        </Routes>
      </Suspense>
    </HashRouter>
  )
}

function RouteLoading() {
  return (
    <div className="route-loading">
      <Spin />
    </div>
  )
}
