import {
  type MouseEvent,
  useCallback,
  useEffect,
  useMemo,
  useState,
} from "react";
import { ChevronDown, ChevronRight, Train } from "lucide-react";
import { Stack, Group, Text, Box, UnstyledButton, NavLink } from "@mantine/core";

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

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 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 (
          <Stack key={key} gap={4}>
            <UnstyledButton
              onClick={() => toggleExpanded(key)}
              style={{
                background: groupActive ? "var(--mantine-color-green-1)" : "transparent",
                padding: "8px 12px",
                borderRadius: "8px",
                width: "100%",
                cursor: "pointer",
              }}
            >
              <Group justify="space-between">
                <Text size="xs" fw={600} c={groupActive ? "green" : "dimmed"} tt="uppercase">
                  {child.label}
                </Text>
                <ChevronDown
                  size={14}
                  style={{
                    transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)",
                    transition: "transform 0.2s",
                    color: groupActive ? "var(--mantine-color-green-6)" : "var(--mantine-color-gray-5)",
                  }}
                />
              </Group>
            </UnstyledButton>
            {isOpen && (
              <Stack gap={2} style={{ paddingLeft: "12px", borderLeft: "2px solid var(--mantine-color-green-2)" }}>
                {renderNavBranch(child.children!, depth + 1, key)}
              </Stack>
            )}
          </Stack>
        );
      }

      if (!child.href) return null;

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

      return (
        <NavLink
          key={key}
          component="a"
          href={child.href}
          onClick={(e) => navigateTo(e as any, child.href!)}
          label={child.label}
          active={childActiveHref}
          color="green"
          style={{
            borderRadius: "8px",
            cursor: "pointer",
            fontSize: "14px",
          }}
          rightSection={<ChevronRight size={16} />}
        />
      );
    });

  const renderIconWell = (icon: React.ReactNode, active: boolean) => {
    if (!icon) return null;
    return (
      <Box
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          width: "30px",
          height: "30px",
          borderRadius: "8px",
          flexShrink: 0,
          background: active
            ? "linear-gradient(135deg, #10b981 0%, #059669 100%)"
            : "var(--mantine-color-gray-1)",
          color: active ? "white" : "var(--mantine-color-gray-6)",
          boxShadow: active ? "0 2px 6px rgba(16, 185, 129, 0.25)" : "none",
          transition: "all 0.2s ease",
        }}
      >
        {icon}
      </Box>
    );
  };

  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 (
      <Stack key={item.href} gap={0}>
        <NavLink
          component="a"
          href={item.href}
          onClick={(e) => navigateTo(e as any, item.href!)}
          label={item.label}
          leftSection={renderIconWell(item.icon, isActive)}
          active={leafActive}
          color="green"
          variant="light"
          style={{
            borderRadius: "10px",
            cursor: "pointer",
            fontSize: "14px",
            fontWeight: 500,
            padding: "8px 10px",
          }}
          rightSection={
            hasChildren ? (
              <ChevronDown
                size={16}
                style={{
                  transform: isOpen ? "rotate(0deg)" : "rotate(-90deg)",
                  transition: "transform 0.2s",
                }}
                onClick={(e) => {
                  e.preventDefault();
                  toggleExpanded(item.href!);
                }}
              />
            ) : (
              <ChevronRight size={16} />
            )
          }
        />

        {hasChildren && isOpen && (
          <Stack gap={4} style={{ paddingLeft: "16px", borderLeft: "2px solid var(--mantine-color-green-2)" }}>
            {renderNavBranch(item.children!, 0, item.href)}
          </Stack>
        )}
      </Stack>
    );
  };

  return (
    <Box
      component="aside"
      style={{
        height: "100%",
        maxHeight: "100%",
        width: "280px",
        flexShrink: 0,
        borderRadius: "12px",
        border: "1px solid var(--mantine-color-gray-2)",
        background: "white",
        boxShadow: "0 1px 3px rgba(0, 0, 0, 0.05)",
        display: "flex",
        flexDirection: "column",
        overflow: "hidden",
      }}
    >
      <Group
        gap={12}
        px="lg"
        py="md"
        style={{
          borderBottom: "1px solid var(--mantine-color-gray-2)",
          flexShrink: 0,
          height: "80px",
        }}
        wrap="nowrap"
      >
        <Box
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            width: "44px",
            height: "44px",
            borderRadius: "12px",
            background: "linear-gradient(135deg, #10b981 0%, #059669 100%)",
            boxShadow: "0 4px 12px rgba(16, 185, 129, 0.3)",
            flexShrink: 0,
          }}
        >
          <Train size={24} color="white" strokeWidth={2} />
        </Box>
        <Stack gap={0} style={{ minWidth: 0 }}>
          <Text size="md" fw={700} style={{ letterSpacing: "-0.3px", lineHeight: 1.2 }}>
            EDR Freight
          </Text>
          <Text size="xs" c="dimmed" fw={500} style={{ letterSpacing: "0.3px" }}>
            Backoffice
          </Text>
        </Stack>
      </Group>

      <Stack
        component="nav"
        gap="lg"
        p="md"
        style={{
          flex: 1,
          minHeight: 0,
          overflowY: "auto",
          overscrollBehavior: "contain",
        }}
      >
        {sections.map((section) => (
          <Stack key={section.title} gap={8}>
            <Text size="xs" fw={600} c="dimmed" tt="uppercase" style={{ letterSpacing: "0.5px", paddingLeft: "8px" }}>
              {section.title}
            </Text>
            <Stack gap={2}>
              {section.items.map((item) => renderTopLevelItem(item))}
            </Stack>
          </Stack>
        ))}
      </Stack>
    </Box>
  );
};

export default FreightSidebar;
