import { MetaProvider, Title } from "@solidjs/meta";
import { Router, useLocation, Navigate } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import { Show, Suspense } from "solid-js";
import { ThemeProvider } from "./lib/theme";
import { ClerkProvider } from "clerk-solidjs/start";
import { ClerkLoaded, ClerkLoading, useAuth } from "clerk-solidjs";
import { AppShell } from "./components/layout";
import { ToastProvider, ErrorBoundary, PageTransition } from "./components/ui";

import "./app.css";

const PROTECTED_PATHS = ["/dashboard", "/onboarding"];

function pathMatches(pathname: string, prefixes: string[]): boolean {
  return prefixes.some(
    (p) => pathname === p || pathname.startsWith(p + "/"),
  );
}

function RouteGuard() {
  const location = useLocation();
  const auth = useAuth();

  const redirect = () => {
    const pathname = location.pathname;

    if (
      auth.isLoaded() &&
      !auth.isSignedIn() &&
      pathMatches(pathname, PROTECTED_PATHS)
    ) {
      return "/login";
    }

    return undefined;
  };

  return (
    <Show when={redirect()} keyed>
      {(to) => <Navigate href={to} />}
    </Show>
  );
}

function ClerkApp(props: { children: any }) {
  return (
    <ClerkProvider
      publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}
    >
      <Suspense>
        <ClerkLoaded>
          <RouteGuard />
        </ClerkLoaded>
        <ClerkLoading>
          <div class="h-16 animate-pulse bg-[var(--color-bg-secondary)]" />
        </ClerkLoading>
      </Suspense>
      <Suspense>{props.children}</Suspense>
    </ClerkProvider>
  );
}

export default function App() {
  return (
    <MetaProvider>
      <Title>Kordant</Title>
      <ThemeProvider>
        <ToastProvider>
          <Router
            root={(props) => (
              <ClerkApp>
                <AppShell>
                  <a
                    href="#main-content"
                    class="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-[100] focus:px-4 focus:py-2 focus:bg-[var(--color-bg)] focus:text-[var(--color-text-primary)] focus:rounded-lg focus:shadow-lg focus:outline-2 focus:outline-[var(--color-focus-ring)]"
                  >
                    Skip to main content
                  </a>
                  <ErrorBoundary>
                    <Suspense>
                      <PageTransition>
                        {props.children}
                      </PageTransition>
                    </Suspense>
                  </ErrorBoundary>
                </AppShell>
              </ClerkApp>
            )}
          >
            <FileRoutes />
          </Router>
        </ToastProvider>
      </ThemeProvider>
    </MetaProvider>
  );
}
