"use client";

import { useEffect, useState } from "react";
import { usePathname, useRouter } from "next/navigation";
import { AppHeader } from "@/components/app/AppHeader";
import { AppSidebar } from "@/components/app/AppSidebar";
import { PageTransition } from "@/components/motion/PageTransition";
import { useAuth } from "@/hooks/useAuth";
import { cn } from "@/lib/utils";

export default function AppLayout({ children }: { children: React.ReactNode }) {
  const { user, hydrated } = useAuth();
  const router = useRouter();
  const pathname = usePathname();
  // Below 1440px the sidebar is always an overlay drawer (same as 1024px),
  // closed by default. Only at 1440px+ does it become a permanent push panel —
  // computed lazily (not in an effect) so that width never renders a collapsed
  // sidebar that then animates open a tick after mount.
  const [sidebarOpen, setSidebarOpen] = useState(
    () => typeof window !== "undefined" && window.matchMedia("(min-width: 1440px)").matches,
  );

  // 1440px+: sidebar stays permanently open — no hamburger to fold it away.
  // The toggle buttons (header hamburger, sidebar close X) are hidden at this
  // width via CSS; this just keeps the state in sync as the viewport crosses it.
  useEffect(() => {
    const mq = window.matchMedia("(min-width: 1440px)");
    function sync(e: MediaQueryList | MediaQueryListEvent) {
      if (e.matches) setSidebarOpen(true);
    }
    sync(mq);
    mq.addEventListener("change", sync);
    return () => mq.removeEventListener("change", sync);
  }, []);

  useEffect(() => {
    if (hydrated && !user) {
      const redirect = encodeURIComponent(pathname);
      router.replace(`/login?redirect=${redirect}`);
    }
  }, [hydrated, user, pathname, router]);

  if (!hydrated || !user) {
    return (
      <div className="grid min-h-screen place-items-center bg-white dark:bg-slate-950">
        <div className="flex items-center gap-3 text-slate-500 dark:text-slate-400">
          <span className="h-2 w-2 animate-pulse rounded-full bg-brand-500" />
          <span className="h-2 w-2 animate-pulse rounded-full bg-brand-500 [animation-delay:120ms]" />
          <span className="h-2 w-2 animate-pulse rounded-full bg-brand-500 [animation-delay:240ms]" />
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-slate-50/60 dark:bg-slate-950">
      <div
        className={cn(
          "min-[1440px]:grid transition-[grid-template-columns] duration-300 ease-snappy",
          sidebarOpen ? "min-[1440px]:grid-cols-[18rem_1fr]" : "min-[1440px]:grid-cols-[0rem_1fr]",
        )}
      >
        <AppSidebar open={sidebarOpen} onClose={() => setSidebarOpen(false)} />
        <div className="flex min-h-screen flex-col">
          <AppHeader sidebarOpen={sidebarOpen} onMenuClick={() => setSidebarOpen((v) => !v)} />
          {/* pt-4 mirrors the sidebar nav's own p-4 top offset (AppSidebar.tsx) so the
              first row of main content lines up with the active nav item, instead
              of sitting lower under the header. Bottom keeps the roomier pb-8 rhythm. */}
          <main id="main-content" className="flex-1 pt-4 pb-8">
            <PageTransition>{children}</PageTransition>
          </main>
        </div>
      </div>
    </div>
  );
}
