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

import { getAdminRole, hasAdminSession } from '@/utils/admin-auth'
import { isWorkerSite, WORKER_SITE_ORIGIN } from '@/utils/site'
import { hasWorkerSession } from '@/utils/worker-auth'
import { resolveLegacyWorkerPath } from '@/utils/worker-routes'
import AdminLayout from '@/layouts/AdminLayout'
import WorkerLayout from '@/layouts/WorkerLayout'

const AdminDashboardPage = lazy(() => import('@/pages/admin/AdminDashboardPage'))
const AdminFinancePage = lazy(() => import('@/pages/admin/AdminFinancePage'))
const AdminAuditLogsPage = lazy(() => import('@/pages/admin/AdminAuditLogsPage'))
const AdminCloudtentaclesRecordsPage = lazy(
  () => import('@/pages/admin/AdminCloudtentaclesRecordsPage'),
)
const AdminKuaishouIndustryPage = lazy(() => import('@/pages/admin/AdminKuaishouIndustryPage'))
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 AdminDevMockPage = lazy(() => import('@/pages/admin/AdminDevMockPage'))
const AdminWorkerPlatformPage = lazy(() => import('@/pages/admin/AdminWorkerPlatformPage'))
const ClaimPage = lazy(() => import('@/pages/claim/ClaimPage'))
const CollectPage = lazy(() => import('@/pages/collect/CollectPage'))
const NotFoundPage = lazy(() => import('@/pages/NotFoundPage'))
const WorkerHallPage = lazy(() => import('@/pages/worker/WorkerHallPage'))
const WorkerLoginPage = lazy(() => import('@/pages/worker/WorkerLoginPage'))
const WorkerOrdersPage = lazy(() => import('@/pages/worker/WorkerOrdersPage'))
const WorkerAfterSalesPage = lazy(() => import('@/pages/worker/WorkerAfterSalesPage'))
const WorkerProfilePage = lazy(() => import('@/pages/worker/WorkerProfilePage'))

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' | 'finance'> }) {
  if (!roles.includes(getAdminRole())) {
    return (
      <Navigate to={getAdminRole() === 'finance' ? '/admin/finance' : '/admin/dashboard'} replace />
    )
  }

  return <Outlet />
}

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

  return <AdminLoginPage />
}

function RequireWorker() {
  const location = useLocation()

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

  return <Outlet />
}

export default function App() {
  const legacyWorkerPath = resolveLegacyWorkerPath(window.location.hash)

  if (legacyWorkerPath) {
    return <WorkerSiteRedirect path={legacyWorkerPath} />
  }

  if (isWorkerSite()) {
    return <WorkerApplication />
  }

  return <AdminApplication />
}

function AdminApplication() {
  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 element={<RequireRole roles={['admin', 'operator', 'support']} />}>
                <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>
              <Route element={<RequireRole roles={['admin', 'operator', 'finance']} />}>
                <Route path="finance" element={<AdminFinancePage />} />
              </Route>
              <Route path="worker-platform" element={<AdminWorkerPlatformPage />} />
              <Route element={<RequireRole roles={['admin', 'operator', 'support']} />}>
                <Route path="kuaishou-industry" element={<AdminKuaishouIndustryPage />} />
                <Route path="cloudtentacles-records" element={<AdminCloudtentaclesRecordsPage />} />
                <Route path="dev-mock" element={<AdminDevMockPage />} />
              </Route>
              <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="/collect" element={<CollectPage />} />
          <Route path="*" element={<NotFoundPage />} />
        </Routes>
      </Suspense>
    </HashRouter>
  )
}

function WorkerApplication() {
  return (
    <BrowserRouter>
      <Suspense fallback={<RouteLoading />}>
        <Routes>
          <Route path="/" element={<WorkerLoginPage />} />
          <Route element={<RequireWorker />}>
            <Route element={<WorkerLayout />}>
              <Route path="hall" element={<WorkerHallPage />} />
              <Route path="orders" element={<WorkerOrdersPage />} />
              <Route path="orders/after-sales" element={<WorkerAfterSalesPage />} />
              <Route path="profile" element={<WorkerProfilePage />} />
            </Route>
          </Route>
          <Route path="*" element={<Navigate to="/" replace />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  )
}

function WorkerSiteRedirect({ path }: { path: string }) {
  useEffect(() => {
    window.location.replace(`${WORKER_SITE_ORIGIN}${path}`)
  }, [path])

  return <RouteLoading />
}

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