"use client";

import { useState, useEffect, useMemo, useRef } from "react";
import { usePathname, useRouter } from "next/navigation";
import { useAuthStore, useAuthSession } from "@/features/auth/stores/auth.store";
import { useActiveSubscriptions } from "@/features/subscriptions/hooks";
import { accountService } from "@/features/account/api/account.api";
import { Sidebar } from "./Sidebar";
import { Header } from "./Header";
import { computeNavigation, type NavigationItem } from "./navigation";
import type { Subscription } from "@customer-portal/domain/subscriptions";

interface AppShellProps {
  children: React.ReactNode;
}

function collectPrefetchUrls(navigation: NavigationItem[]): string[] {
  const hrefs = new Set<string>();
  for (const item of navigation) {
    if (item.href && item.href !== "#") hrefs.add(item.href);
    if (!item.children || item.children.length === 0) continue;
    // Prefetch only the first few children to avoid heavy prefetch
    for (const child of item.children.slice(0, 5)) {
      if (child.href && child.href !== "#") hrefs.add(child.href);
    }
  }
  return [...hrefs];
}

// Sidebar and navigation are modularized in ./Sidebar and ./navigation

export function AppShell({ children }: AppShellProps) {
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const { user, isAuthenticated } = useAuthSession();
  const checkAuth = useAuthStore(state => state.checkAuth);
  const hasCheckedAuth = useAuthStore(state => state.hasCheckedAuth);
  const loading = useAuthStore(state => state.loading);
  const hydrateUserProfile = useAuthStore(state => state.hydrateUserProfile);
  const pathname = usePathname();
  const router = useRouter();
  const activeSubscriptionsQuery = useActiveSubscriptions();
  const activeSubscriptions: Subscription[] = useMemo(
    () => activeSubscriptionsQuery.data ?? [],
    [activeSubscriptionsQuery.data]
  );

  // Initialize with a stable default to avoid hydration mismatch
  const [expandedItems, setExpandedItems] = useState<string[]>([]);

  // Save expanded items to localStorage
  useEffect(() => {
    if (typeof window !== "undefined") {
      localStorage.setItem("sidebar-expanded-items", JSON.stringify(expandedItems));
    }
  }, [expandedItems]);

  // Load saved expanded items after mount to keep initial SSR/CSR markup identical
  useEffect(() => {
    try {
      const saved = localStorage.getItem("sidebar-expanded-items");
      if (!saved) return;
      const parsed = JSON.parse(saved) as unknown;
      if (Array.isArray(parsed) && parsed.every(x => typeof x === "string")) {
        setExpandedItems(prev => {
          const next = parsed;
          if (next.length === prev.length && next.every(v => prev.includes(v))) return prev;
          return next;
        });
      }
    } catch {
      // ignore
    }
  }, []);

  // Track if we've initiated auth check to prevent duplicate calls
  const authCheckInitiated = useRef(false);

  useEffect(() => {
    if (!hasCheckedAuth && !authCheckInitiated.current) {
      authCheckInitiated.current = true;
      void checkAuth();
    }
  }, [hasCheckedAuth, checkAuth]);

  useEffect(() => {
    if (hasCheckedAuth && !isAuthenticated && !loading) {
      const destination = pathname || "/account";
      router.push(`/auth/login?redirect=${encodeURIComponent(destination)}`);
    }
  }, [hasCheckedAuth, isAuthenticated, loading, pathname, router]);

  // Hydrate full profile once after auth so header name is consistent across pages
  useEffect(() => {
    if (!hasCheckedAuth || !isAuthenticated) return;
    // Only hydrate if we don't have basic profile details yet
    if (user?.firstname && user?.lastname) return;
    void (async () => {
      try {
        const prof = await accountService.getProfile();
        if (!prof) {
          return;
        }
        hydrateUserProfile({
          firstname: prof.firstname ?? undefined,
          lastname: prof.lastname ?? undefined,
          phonenumber: prof.phonenumber ?? undefined,
        });
      } catch {
        // best-effort profile hydration; ignore errors
      }
    })();
  }, [hasCheckedAuth, hydrateUserProfile, isAuthenticated, user?.firstname, user?.lastname]);

  // Auto-expand sections when browsing their routes
  useEffect(() => {
    setExpandedItems(prev => {
      const next = new Set(prev);
      if (pathname.startsWith("/account/subscriptions")) next.add("Subscriptions");
      if (pathname.startsWith("/account/billing")) next.add("Billing");
      if (pathname.startsWith("/account/support")) next.add("Support");
      if (pathname.startsWith("/account/settings")) next.add("Settings");
      const result = [...next];
      // Avoid state update if unchanged
      if (result.length === prev.length && result.every(v => prev.includes(v))) return prev;
      return result;
    });
  }, [pathname]);

  const toggleExpanded = (itemName: string) => {
    setExpandedItems(prev =>
      prev.includes(itemName) ? prev.filter(name => name !== itemName) : [...prev, itemName]
    );
  };

  // Memoize navigation to prevent unnecessary re-renders
  const navigation = useMemo(() => computeNavigation(activeSubscriptions), [activeSubscriptions]);

  // Proactively prefetch primary routes to speed up first navigation
  useEffect(() => {
    try {
      const urls = collectPrefetchUrls(navigation);
      for (const href of urls) {
        try {
          router.prefetch(href);
        } catch {
          // best-effort prefetch, ignore errors (dev or unsupported)
        }
      }
    } catch {
      // ignore
    }
  }, [navigation, router]);

  // Determine if we should show loading state in content area
  // Auth must be checked before rendering protected content
  const isAuthReady = hasCheckedAuth && isAuthenticated;
  const isCheckingAuth = !hasCheckedAuth || loading;

  return (
    <>
      <div className="h-screen flex overflow-hidden bg-background">
        {/* Mobile sidebar overlay */}
        {sidebarOpen && (
          <div className="fixed inset-0 flex z-50 md:hidden">
            <div
              className="fixed inset-0 bg-black/50 animate-in fade-in duration-300"
              onClick={() => setSidebarOpen(false)}
            />
            <div className="relative flex-1 flex flex-col max-w-xs w-full bg-sidebar border-r border-sidebar-border animate-in slide-in-from-left duration-300 shadow-2xl">
              <div className="absolute top-0 right-0 -mr-12 pt-2" />
              <Sidebar
                navigation={navigation}
                pathname={pathname}
                expandedItems={expandedItems}
                toggleExpanded={toggleExpanded}
                isMobile
              />
            </div>
          </div>
        )}

        {/* Desktop sidebar */}
        <div className="hidden md:flex md:flex-shrink-0">
          <div className="flex flex-col w-[240px] border-r border-sidebar-border bg-sidebar shadow-sm">
            <Sidebar
              navigation={navigation}
              pathname={pathname}
              expandedItems={expandedItems}
              toggleExpanded={toggleExpanded}
            />
          </div>
        </div>

        {/* Main content */}
        <div className="flex flex-col w-0 flex-1 overflow-hidden bg-background">
          {/* Header */}
          <Header
            onMenuClick={() => setSidebarOpen(true)}
            user={user}
            profileReady={!!(user?.firstname || user?.lastname)}
          />

          {/* Main content area */}
          <main className="flex-1 relative overflow-y-auto focus:outline-none">
            {isCheckingAuth ? (
              <div className="p-6 md:p-8 lg:p-10">
                <div className="space-y-6 animate-pulse">
                  <div className="space-y-3">
                    <div className="h-4 bg-muted rounded w-24" />
                    <div className="h-8 bg-muted rounded w-48" />
                  </div>
                  <div className="h-32 bg-muted rounded-xl" />
                  <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
                    <div className="h-40 bg-muted rounded-xl" />
                    <div className="h-40 bg-muted rounded-xl" />
                  </div>
                </div>
              </div>
            ) : isAuthReady ? (
              children
            ) : null}
          </main>
        </div>
      </div>

      {/* Global utilities are mounted in RootLayout */}
    </>
  );
}
