import { Router, Route, useLocation, useNavigate } from "@solidjs/router";
import { createEffect, createSignal, on, onCleanup, Show, Suspense, lazy } from "solid-js";
import AppShell from "~/components/app-shell";
import { authClient } from "~/lib/auth-client";
import { AppProvider } from "~/lib/app-context";
import "./app.css";

// Lazy load routes
const LoginPage = lazy(() => import("~/routes/login"));
const NotFoundPage = lazy(() => import("~/routes/[...404]"));
const AcceptInvitePage = lazy(() => import("~/routes/accept-invite/[token]"));
const TodayRoute = lazy(() => import("~/routes/app/[workspaceSlug]/today"));
const CalendarRoute = lazy(() => import("~/routes/app/[workspaceSlug]/calendar"));
const BoardRoute = lazy(() => import("~/routes/app/[workspaceSlug]/board"));
const MailRoute = lazy(() => import("~/routes/app/[workspaceSlug]/mail"));
const NotesRoute = lazy(() => import("~/routes/app/[workspaceSlug]/notes"));
const FocusRoute = lazy(() => import("~/routes/app/[workspaceSlug]/focus"));
const SettingsRoute = lazy(() => import("~/routes/app/[workspaceSlug]/settings"));

function RootFrame(props: { children: unknown }) {
  const location = useLocation();
  const navigate = useNavigate();
  const session = authClient.useSession();
  const [sessionTimeoutReached, setSessionTimeoutReached] = createSignal(false);
  let sessionTimeoutId: number | undefined;
  const inApp = () => location.pathname.startsWith("/app/");
  const inLogin = () => location.pathname === "/login";

  createEffect(
    on(
      () => session().isPending,
      isPending => {
        if (!isPending) {
          setSessionTimeoutReached(false);
          if (sessionTimeoutId !== undefined) {
            window.clearTimeout(sessionTimeoutId);
            sessionTimeoutId = undefined;
          }
          return;
        }

        if (sessionTimeoutId !== undefined) {
          return;
        }

        sessionTimeoutId = window.setTimeout(() => {
          setSessionTimeoutReached(true);
          sessionTimeoutId = undefined;
        }, 2000);
      },
      { defer: true }
    )
  );

  onCleanup(() => {
    if (sessionTimeoutId !== undefined) {
      window.clearTimeout(sessionTimeoutId);
    }
  });

  createEffect(() => {
    const current = session();
    if (current.isPending && !sessionTimeoutReached()) {
      return;
    }

    if (inApp() && !current.data) {
      navigate("/login", { replace: true });
      return;
    }

    if (inLogin() && current.data) {
      navigate("/app/personal/today", { replace: true });
    }
  });

  const loadingGate = () => inApp() && session().isPending && !sessionTimeoutReached();
  const canRenderApp = () => !inApp() || Boolean(session().data);

  return (
    <Show
      when={!loadingGate()}
      fallback={
        <main class="flex min-h-screen items-center justify-center px-4">
          <div class="app-surface w-full max-w-xl rounded-[2rem] p-8 text-center">
            <p class="section-title">Securing Session</p>
            <h1 class="mt-3 text-3xl font-extrabold tracking-[-0.05em]">Loading your workspace shell…</h1>
            <p class="mt-3 text-sm text-soft">Checking the active Better Auth session before opening Productier.</p>
          </div>
        </main>
      }
    >
      <Show when={inApp()} fallback={<Suspense>{props.children}</Suspense>}>
        <Show when={canRenderApp()}>
          <AppShell>
            <Suspense>{props.children}</Suspense>
          </AppShell>
        </Show>
      </Show>
    </Show>
  );
}

export default function App() {
  return (
    <AppProvider>
      <Router root={props => <RootFrame>{props.children}</RootFrame>}>
        <Route path="/" component={() => {
          const navigate = useNavigate();
          createEffect(() => navigate("/login", { replace: true }));
          return null;
        }} />
        <Route path="/login" component={LoginPage} />
        <Route path="/accept-invite/:token" component={AcceptInvitePage} />
        <Route path="/app/:workspaceSlug">
          <Route path="/today" component={TodayRoute} />
          <Route path="/calendar" component={CalendarRoute} />
          <Route path="/board" component={BoardRoute} />
          <Route path="/mail" component={MailRoute} />
          <Route path="/notes" component={NotesRoute} />
          <Route path="/focus" component={FocusRoute} />
          <Route path="/settings" component={SettingsRoute} />
          <Route path="/" component={() => {
            const navigate = useNavigate();
            const location = useLocation();
            createEffect(() => {
              const slug = location.pathname.split("/")[2];
              navigate(`/app/${slug}/today`, { replace: true });
            });
            return null;
          }} />
        </Route>
        <Route path="*" component={NotFoundPage} />
      </Router>
    </AppProvider>
  );
}
