import { type MouseEvent, useCallback, useEffect, useMemo, useState } from "react";
import { ChevronDown, ChevronRight } from "lucide-react";

import { cn } from "@/lib/utils";

import type { SidebarItem, SidebarSection } from "./types";

const EDR_LOGO = "/assets/logo.svg";

export interface FreightSidebarProps {
  sections: SidebarSection[];
  activeHref?: string;
  onNavigate?: (href: string) => void;
}

const sidebarItemKey = (item: SidebarItem, parentKey: string) =>
  item.href ?? `${parentKey}::${item.label}`;

const collectSidebarHrefs = (items: SidebarItem[]): string[] =>
  items.flatMap((item) => {
    const hrefs: string[] = [];
    if (item.href) hrefs.push(item.href.toLowerCase());
    if (item.children?.length) hrefs.push(...collectSidebarHrefs(item.children));
    return hrefs;
  });

const flattenSectionItems = (sections: SidebarSection[]) =>
  sections.flatMap((section) => section.items);

const FreightSidebar = ({ sections, activeHref, onNavigate }: FreightSidebarProps) => {
  const items = useMemo(() => flattenSectionItems(sections), [sections]);
  const activePath = activeHref?.toLowerCase() ?? "";

  const isHrefActive = useCallback(
    (href: string) => {
      const normalized = href.toLowerCase();
      return activePath === normalized || activePath.startsWith(`${normalized}/`);
    },
    [activePath],
  );

  const branchContainsActive = useCallback(
    (branch: SidebarItem[]) =>
      collectSidebarHrefs(branch).some((href) => isHrefActive(href)),
    [isHrefActive],
  );

  const defaultExpanded = useMemo(() => {
    const acc: Record<string, boolean> = {};

    const walk = (entries: SidebarItem[], parentKey: string) => {
      for (const entry of entries) {
        if (!entry.children?.length) continue;
        const key = sidebarItemKey(entry, parentKey);
        acc[key] =
          branchContainsActive(entry.children) ||
          (entry.href ? isHrefActive(entry.href) : false);
        walk(entry.children, key);
      }
    };

    for (const item of items) {
      if (!item.children?.length) continue;
      const key = item.href ?? item.label;
      acc[key] =
        activePath === key.toLowerCase() ||
        activePath.startsWith(`${key.toLowerCase()}/`) ||
        branchContainsActive(item.children);
      walk(item.children, key);
    }

    return acc;
  }, [activePath, branchContainsActive, isHrefActive, items]);

  const [expanded, setExpanded] = useState<Record<string, boolean>>(defaultExpanded);

  useEffect(() => {
    setExpanded((current) => ({ ...defaultExpanded, ...current }));
  }, [defaultExpanded]);

  const navigateTo = (event: MouseEvent<HTMLAnchorElement>, href: string) => {
    if (onNavigate) {
      event.preventDefault();
      onNavigate(href);
    }
  };

  const toggleExpanded = (key: string) => {
    setExpanded((current) => ({ ...current, [key]: !current[key] }));
  };

  const navLinkClass = (active: boolean, depth: number) =>
    cn(
      "flex items-center justify-between rounded-md px-3 py-2.5 text-base font-medium leading-snug transition-colors",
      active
        ? "bg-primary text-primary-foreground shadow-sm"
        : "text-gray-900 hover:bg-gray-100",
      depth > 0 && "text-[15px]",
    );

  const iconClass = (active: boolean, sectionActive: boolean) =>
    cn(
      "flex h-5 w-5 shrink-0 items-center justify-center [&_svg]:h-5 [&_svg]:w-5",
      active
        ? "text-primary-foreground"
        : sectionActive
          ? "text-gray-900"
          : "text-gray-900",
    );

  const renderNavBranch = (children: SidebarItem[], depth: number, parentKey: string) =>
    children.map((child) => {
      const key = sidebarItemKey(child, parentKey);
      const isGroup = Boolean(child.children?.length) && !child.href;

      if (isGroup) {
        const isOpen = expanded[key] ?? false;
        const groupActive = branchContainsActive(child.children!);

        return (
          <div key={key} className="flex flex-col gap-0.5">
            <button
              type="button"
              aria-expanded={isOpen}
              onClick={() => toggleExpanded(key)}
              className={cn(
                "flex w-full items-center justify-between rounded-md px-3 py-2 text-left text-xs font-semibold uppercase tracking-wide transition-colors",
                groupActive
                  ? "bg-gray-100 text-gray-900"
                  : "text-gray-900 hover:bg-gray-100",
              )}
            >
              <span className="truncate">{child.label}</span>
              <ChevronDown
                className={cn(
                  "h-4 w-4 shrink-0 text-gray-900 transition-transform",
                  isOpen ? "rotate-0" : "-rotate-90",
                )}
              />
            </button>
            {isOpen ? (
              <div
                className={cn(
                  "flex flex-col gap-0.5 border-l border-gray-200",
                  depth === 0 ? "ml-3 pl-2" : "ml-2 pl-2",
                )}
              >
                {renderNavBranch(child.children!, depth + 1, key)}
              </div>
            ) : null}
          </div>
        );
      }

      if (!child.href) return null;

      const childHref = child.href.toLowerCase();
      const childActiveHref = isHrefActive(childHref);

      return (
        <a
          key={key}
          href={child.href}
          onClick={(event) => navigateTo(event, child.href!)}
          aria-current={childActiveHref ? "page" : undefined}
          className={navLinkClass(childActiveHref, depth)}
        >
          <span className="truncate">{child.label}</span>
          <ChevronRight
            className={cn(
              "h-4 w-4 shrink-0",
              childActiveHref ? "text-primary-foreground/80" : "text-gray-900",
            )}
          />
        </a>
      );
    });

  const renderTopLevelItem = (item: SidebarItem) => {
    if (!item.href) return null;

    const hasChildren = Boolean(item.children?.length);
    const itemHref = item.href.toLowerCase();
    const childActive = hasChildren ? branchContainsActive(item.children!) : false;
    const isCurrentItem = hasChildren
      ? activePath === itemHref
      : isHrefActive(itemHref);
    const isSectionActive = childActive && !isCurrentItem;
    const isActive = isCurrentItem || isSectionActive;
    const isOpen = expanded[item.href] ?? false;
    const leafActive = isCurrentItem && !hasChildren;

    return (
      <div key={item.href} className="flex flex-col gap-0.5">
        <div
          className={cn(
            "group flex items-center rounded-md transition-colors",
            leafActive
              ? "bg-primary text-primary-foreground shadow-sm"
              : isSectionActive || (hasChildren && isCurrentItem)
                ? "bg-gray-100 text-gray-900"
                : "text-gray-900 hover:bg-gray-100",
          )}
        >
          <a
            href={item.href}
            onClick={(event) => navigateTo(event, item.href!)}
            aria-current={isCurrentItem ? "page" : undefined}
            className="flex min-w-0 flex-1 items-center gap-3 px-3 py-2.5 text-base font-medium leading-snug"
          >
            {item.icon ? (
              <span className={iconClass(leafActive, isActive)}>{item.icon}</span>
            ) : null}
            <span className="truncate">{item.label}</span>
          </a>

          {hasChildren ? (
            <button
              type="button"
              aria-label={`Toggle ${item.label}`}
              aria-expanded={isOpen}
              onClick={() => toggleExpanded(item.href!)}
              className={cn(
                "mr-2 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md transition-colors",
                leafActive
                  ? "text-primary-foreground hover:bg-white/10"
                  : "text-gray-900 hover:bg-gray-200/80",
              )}
            >
              <ChevronDown
                className={cn(
                  "h-4 w-4 transition-transform",
                  isOpen ? "rotate-0" : "-rotate-90",
                )}
              />
            </button>
          ) : (
            <span
              className={cn(
                "mr-3 flex h-4 w-4 shrink-0 items-center justify-center",
                leafActive ? "text-primary-foreground/80" : "text-gray-900",
              )}
              aria-hidden
            >
              <ChevronRight className="h-4 w-4" />
            </span>
          )}
        </div>

        {hasChildren && isOpen ? (
          <div className="ml-3 flex flex-col gap-1 border-l border-gray-200 pl-2">
            {renderNavBranch(item.children!, 0, item.href)}
          </div>
        ) : null}
      </div>
    );
  };

  return (
    <aside className="flex h-full max-h-full w-[340px] shrink-0 flex-col overflow-hidden rounded-lg border border-gray-200 bg-white shadow-sm">
      <div className="flex shrink-0 items-center gap-2.5 border-b border-gray-100 px-5 py-5">
        <img src={EDR_LOGO} alt="EDR Freight" className="h-9 w-auto" />
        <span className="text-lg font-semibold tracking-tight text-gray-900">EDR Freight</span>
      </div>

      <nav className="flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto overscroll-contain px-3 py-4">
        {sections.map((section) => (
          <div key={section.title} className="flex flex-col gap-1">
            <p
              className={cn(
                "px-3 pb-1 text-xs font-semibold uppercase tracking-wide",
                section.mutedTitle ? "text-gray-500" : "text-gray-900",
              )}
            >
              {section.title}
            </p>
            {section.items.map((item) => renderTopLevelItem(item))}
          </div>
        ))}
      </nav>
    </aside>
  );
};

export default FreightSidebar;
