"use client";

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

interface AppShellProps {
  children: React.ReactNode;
}

// 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
    }
  }, []);

  useEffect(() => {
    if (!hasCheckedAuth) {
      void checkAuth();
    }
  }, [hasCheckedAuth, checkAuth]);

  useEffect(() => {
    if (hasCheckedAuth && !isAuthenticated && !loading) {
      router.push("/auth/login");
    }
  }, [hasCheckedAuth, isAuthenticated, loading, 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("/subscriptions")) next.add("Subscriptions");
      if (pathname.startsWith("/billing")) next.add("Billing");
      if (pathname.startsWith("/support")) next.add("Support");
      if (pathname.startsWith("/account")) next.add("Account");
      const result = Array.from(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 hrefs = new Set<string>();
      navigation.forEach(item => {
        if (item.href && item.href !== "#") hrefs.add(item.href);
        if (item.children && item.children.length > 0) {
          // Prefetch only the first few children to avoid heavy prefetch
          item.children.slice(0, 5).forEach(child => {
            if (child.href && child.href !== "#") hrefs.add(child.href);
          });
        }
      });
      hrefs.forEach(href => {
        try {
          router.prefetch(href);
        } catch {
          // best-effort prefetch, ignore errors (dev or unsupported)
        }
      });
    } catch {
      // ignore
    }
  }, [navigation, router]);

  // Do not block the shell; sidebar/header remain mounted. The content area can handle its own 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-[var(--cp-sidebar-bg)] border-r border-[var(--cp-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-[var(--cp-sidebar-border)] bg-[var(--cp-sidebar-bg)] 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">
          {/* 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">{children}</main>
        </div>
      </div>

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