import { createRootRoute, createRoute, createRouter, RouterProvider, Outlet, redirect } from "@tanstack/react-router"
import Dashboard from "./pages/Dashboard"
import Login from "./pages/Login"
import TimeEntries from "./pages/TimeEntries"
import Customers from "./pages/Customers"
import CustomerDetail from "./pages/CustomerDetail"
import Projects from "./pages/Projects"
import ProjectDetail from "./pages/ProjectDetail"
import Profile from "./pages/Profile"
import AdminUsers from "./pages/AdminUsers"
import Settings from "./pages/Settings"
import Calendar from "./pages/Calendar"
import AuditLog from "./pages/AuditLog"
import Documents from "./pages/Documents"
import Nav from "./components/Nav"
import CommandPalette from "./components/CommandPalette"
import { ToastProvider } from "./components/Toast"
import ErrorBoundary from "./components/ErrorBoundary"
import { api } from "./lib/api"

const rootRoute = createRootRoute({
  component: () => (
    <div className="min-h-screen bg-slate-50">
      <Nav />
      <CommandPalette />
      <Outlet />
    </div>
  )
})

const loginRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/login",
  component: Login
})

const authCheck = async () => {
  try {
    await api.getMe()
  } catch (error: any) {
    if (error.status === 401) {
      throw redirect({ to: "/login" })
    }
  }
}

const adminCheck = async () => {
  try {
    const user = await api.getMe()
    if (user.role !== "admin") {
      throw redirect({ to: "/" })
    }
  } catch (error: any) {
    if (error.status === 401) {
      throw redirect({ to: "/login" })
    } else if (error.status === 302 || error.status === 403) {
      throw error
    }
    throw redirect({ to: "/" })
  }
}

const indexRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/",
  beforeLoad: authCheck,
  component: Dashboard
})

const timeEntriesRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/time-entries",
  beforeLoad: authCheck,
  component: TimeEntries
})

const calendarRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/calendar",
  beforeLoad: authCheck,
  component: Calendar
})

const customersRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/customers",
  beforeLoad: authCheck,
  component: Customers
})

const customerDetailRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/customers/$id",
  beforeLoad: authCheck,
  component: CustomerDetail
})

const projectsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/projects",
  beforeLoad: authCheck,
  component: Projects
})

const projectDetailRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/projects/$id",
  beforeLoad: authCheck,
  component: ProjectDetail
})

const documentsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/documents",
  beforeLoad: authCheck,
  component: Documents
})

const profileRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/profile",
  beforeLoad: authCheck,
  component: Profile
})

const adminRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/admin",
  beforeLoad: adminCheck,
  component: AdminUsers
})

const auditLogRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/audit-log",
  beforeLoad: adminCheck,
  component: AuditLog
})

const settingsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/settings",
  beforeLoad: adminCheck,
  component: Settings
})

const routeTree = rootRoute.addChildren([
  indexRoute,
  loginRoute,
  timeEntriesRoute,
  calendarRoute,
  customersRoute,
  customerDetailRoute,
  projectsRoute,
  projectDetailRoute,
  documentsRoute,
  profileRoute,
  adminRoute,
  auditLogRoute,
  settingsRoute
])

const router = createRouter({
  routeTree,
  defaultPreload: "intent"
})

declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router
  }
}

export default function App() {
  return (
    <ToastProvider>
      <ErrorBoundary>
        <RouterProvider router={router} />
      </ErrorBoundary>
    </ToastProvider>
  )
}