import { createRootRoute, createRoute, createRouter, RouterProvider, Outlet, redirect } from "@tanstack/react-router"
import Dashboard from "./pages/Dashboard"
import Login from "./pages/Login"
import ForgotPassword from "./pages/ForgotPassword"
import ResetPassword from "./pages/ResetPassword"
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 Webhooks from "./pages/Webhooks"
import TwoFactorAuth from "./pages/TwoFactorAuth"
import Billing from "./pages/Billing"
import Integrations from "./pages/Integrations"
import ProjectTemplates from "./pages/ProjectTemplates"
import Invoices from "./pages/Invoices"
import Nav from "./components/Nav"
import CommandPalette from "./components/CommandPalette"
import KeyboardHelp from "./components/KeyboardHelp"
import OnboardingTour from "./components/OnboardingTour"
import VersionBadge from "./components/VersionBadge"
import QuickAdd from "./components/QuickAdd"
import { ToastProvider } from "./components/Toast"
import ErrorBoundary from "./components/ErrorBoundary"
import { api } from "./lib/api"

const rootRoute = createRootRoute({
  component: () => (
    <ToastProvider>
      <div className="min-h-screen flex flex-col bg-slate-50">
        <div className="flex-grow">
          <Nav />
          <CommandPalette />
          <KeyboardHelp />
          <OnboardingTour />
          <QuickAdd />
          <Outlet />
        </div>
        <footer className="border-t bg-white py-2 text-center">
          <VersionBadge />
        </footer>
      </div>
    </ToastProvider>
  )
})

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

const forgotPasswordRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/forgot-password",
  component: ForgotPassword
})

const resetPasswordRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/reset-password",
  component: ResetPassword
})

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 invoicesRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/invoices",
  beforeLoad: authCheck,
  component: Invoices
})

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

const twoFactorRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/two-factor",
  beforeLoad: authCheck,
  component: TwoFactorAuth
})

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

const billingRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/billing",
  beforeLoad: authCheck,
  component: Billing
})

const integrationsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/integrations",
  beforeLoad: authCheck,
  component: Integrations
})

const projectTemplatesRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/project-templates",
  beforeLoad: authCheck,
  component: ProjectTemplates
})

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

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

const webhooksRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: "/admin/webhooks",
  beforeLoad: adminCheck,
  component: Webhooks
})

const routeTree = [
  indexRoute,
  loginRoute,
  forgotPasswordRoute,
  resetPasswordRoute,
  timeEntriesRoute,
  calendarRoute,
  customersRoute,
  customerDetailRoute,
  projectsRoute,
  projectDetailRoute,
  documentsRoute,
  invoicesRoute,
  profileRoute,
  twoFactorRoute,
  settingsRoute,
  billingRoute,
  integrationsRoute,
  projectTemplatesRoute,
  adminUsersRoute,
  auditLogRoute,
  webhooksRoute,
]

const router = createRouter({ 
  routeTree,
  defaultCatcher: (error) => <ErrorBoundary error={error} />
})

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

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