"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { ChevronDownIcon, HamburgerIcon } from "@/components/icons";
import { Sheet, SheetTrigger, SheetContent, SheetTitle } from "@/components/ui/sheet";
import type { DocsGroup } from "@/lib/types";

const COLLAPSE_STORAGE_KEY = "docs-sidebar-collapsed";

type SidebarNavProps = {
  groups: DocsGroup[];
  activeSlug: string;
  onNavigate?: () => void;
};

function SidebarNav({ groups, activeSlug, onNavigate }: SidebarNavProps) {
  const initialCollapsed = new Set(
    groups
      .filter((g) => g.section !== "Start Here" && !g.items.some((i) => i.slug === activeSlug))
      .map((g) => g.section),
  );
  const [collapsed, setCollapsed] = useState<Set<string>>(initialCollapsed);
  const restored = useRef(false);

  // Restore the user's expand/collapse choices so navigating between pages
  // does not reset sections the user opened. (The active section is always
  // shown expanded via the `hasActive` check below, regardless of this set.)
  useEffect(() => {
    if (restored.current) return;
    restored.current = true;
    try {
      const stored = sessionStorage.getItem(COLLAPSE_STORAGE_KEY);
      if (stored) setCollapsed(new Set(JSON.parse(stored) as string[]));
    } catch {}
  }, []);

  function toggle(section: string) {
    setCollapsed((prev) => {
      const next = new Set(prev);
      if (next.has(section)) next.delete(section);
      else next.add(section);
      try {
        sessionStorage.setItem(COLLAPSE_STORAGE_KEY, JSON.stringify([...next]));
      } catch {}
      return next;
    });
  }

  return (
    <nav className="px-3 py-4">
      {groups.map((group) => {
        const hasActive = group.items.some((item) => item.slug === activeSlug);
        const isCollapsed = collapsed.has(group.section) && !hasActive;
        return (
          <div key={group.section} className="mb-4">
            <button
              type="button"
              aria-expanded={!isCollapsed}
              onClick={() => toggle(group.section)}
              className="flex w-full cursor-pointer items-center justify-between rounded bg-transparent px-3 py-2 text-[0.6875rem] font-semibold uppercase tracking-[0.06em] text-muted transition hover:text-fg"
            >
              <span>{group.section}</span>
              <ChevronDownIcon className={`shrink-0 transition-transform ${isCollapsed ? "-rotate-90" : ""}`} />
            </button>
            <div
              className={`grid transition-[grid-template-rows] duration-200 ${
                isCollapsed ? "grid-rows-[0fr]" : "grid-rows-[1fr]"
              }`}
            >
              <div className="overflow-hidden">
                {group.items.map((item) => {
                  const active = item.slug === activeSlug;
                  return (
                    <Link
                      key={item.slug}
                      href={item.path}
                      aria-current={active ? "page" : undefined}
                      onClick={onNavigate}
                      className={`block rounded px-3 py-[0.1875rem] text-[0.8125rem] leading-[1.8] no-underline transition hover:text-fg ${
                        active ? "font-medium text-fg" : "text-muted"
                      }`}
                    >
                      {item.title}
                    </Link>
                  );
                })}
              </div>
            </div>
          </div>
        );
      })}
    </nav>
  );
}

type DocsSidebarShellProps = {
  groups: DocsGroup[];
};

function activeDocForPath(groups: DocsGroup[], pathname: string) {
  const normalized = pathname.replace(/\/$/, "") || "/";
  return groups.flatMap((group) => group.items).find((item) => item.path === normalized);
}

export function DocsSidebarShell({ groups }: DocsSidebarShellProps) {
  const pathname = usePathname();
  const activeDoc = activeDocForPath(groups, pathname);
  const activeSlug = activeDoc?.slug ?? "";
  const currentTitle = activeDoc?.title;
  const [open, setOpen] = useState(false);

  return (
    <>
      <Sheet open={open} onOpenChange={setOpen}>
        <SheetTrigger
          aria-label="Open table of contents"
          className="sticky top-14 z-40 flex w-full items-center justify-between border-b border-border bg-bg/80 px-6 py-3 backdrop-blur-sm focus:outline-none md:hidden"
        >
          <span className="text-sm font-medium text-fg">{currentTitle ?? "Documentation"}</span>
          <span className="flex h-8 w-8 items-center justify-center text-muted">
            <HamburgerIcon className="h-4 w-4" />
          </span>
        </SheetTrigger>
        <SheetContent side="left" className="overflow-y-auto p-0" showCloseButton={false}>
          <SheetTitle className="px-6 pt-6">Table of Contents</SheetTitle>
          <SidebarNav groups={groups} activeSlug={activeSlug} onNavigate={() => setOpen(false)} />
        </SheetContent>
      </Sheet>

      <aside
        aria-label="Documentation"
        className="hidden md:sticky md:top-14 md:block md:h-[calc(100vh-3.5rem)] md:w-60 md:overflow-y-auto"
      >
        <SidebarNav groups={groups} activeSlug={activeSlug} />
      </aside>
    </>
  );
}
