// shadcn components

import { cn } from "@xtablo/shared/lib/cn.ts";
import { Avatar, AvatarFallback, AvatarImage } from "@xtablo/ui/components/avatar";
import { Button } from "@xtablo/ui/components/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@xtablo/ui/components/dropdown-menu";
import { TypographyLarge, TypographyMuted } from "@xtablo/ui/components/typography";
import { cva, type VariantProps } from "class-variance-authority";
import {
  Compass,
  ConstructionIcon,
  CreditCard,
  // FileTextIcon, // Notes feature temporarily hidden
  Flame,
  FolderIcon,
  Gem,
  Heart,
  Kanban,
  LayersIcon,
  Leaf,
  ListTodo,
  LogOutIcon,
  MessageCircleIcon,
  MinusIcon,
  PanelsTopLeft,
  PlusIcon,
  SendIcon,
  SettingsIcon,
  Sparkles,
  SquareKanban,
  Star,
  Sun,
  UserMinus,
  Waves,
  Zap,
} from "lucide-react";
import { useState } from "react";
import { Separator } from "react-aria-components";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useLocation } from "react-router-dom";
import { twMerge } from "tailwind-merge";
import { useLogout } from "../hooks/auth";
import { useOrganization, useRemoveOrganizationMember } from "../hooks/organization";
import { useCreateCheckoutSession } from "../hooks/stripe";
import { useTablosList } from "../hooks/tablos";
import { isProd, isStaging } from "../lib/env";
import { useIsReadOnlyUser, useUser } from "../providers/UserStoreProvider";
import { getXtabloIcon } from "../utils/iconHelpers";
import { ThemeSwitcher } from "./ThemeSwitcher";

type NavLinkItem = {
  isActive?: boolean;
  children: React.ReactNode;
};

type NavLinkProps = NavLinkItem;

function NavLink({ isActive, children }: NavLinkProps) {
  return (
    <div
      className={twMerge(
        "group w-full gap-x-3 overflow-hidden px-2.5 py-2 text-nowrap hover:bg-navbar-darker hover:no-underline focus-visible:outline-offset-0 [&>[data-ui=icon]:not([class*=size-])]:size-5",
        "*:data-[ui=notification-badge]:bg-navbar-darker",
        "*:data-[ui=notification-badge]:rounded-md",
        "*:data-[ui=notification-badge]:top-1/2",
        "*:data-[ui=notification-badge]:right-1",
        "*:data-[ui=notification-badge]:-translate-y-1/2",
        "*:data-[ui=notification-badge]:bg-navbar-darker",
        "*:data-[ui=notification-badge]:p-3",
        "*:data-[ui=notification-badge]:text-xs/6",
        "*:data-[ui=notification-badge]:font-semibold",
        isActive
          ? "bg-purple-100 dark:bg-purple-900/30 font-semibold text-[#804EEC] dark:text-purple-300 *:data-[ui=notification-badge]:bg-transparent"
          : [
              "font-medium",
              "text-gray-500 dark:text-gray-300/90 [&:not(:hover)>[data-ui=icon]]:bg-navbar-darker",
            ]
      )}
    >
      {children}
    </div>
  );
}

export function UserMenuPopover({ isCollapsed }: { isCollapsed: boolean }) {
  const user = useUser();
  const { mutate: logout } = useLogout();
  const { data: organizationData } = useOrganization();
  const { mutate: removeOrganizationMember, isPending: isRemovingMember } =
    useRemoveOrganizationMember();
  const { t } = useTranslation("navigation");
  const members = organizationData?.members ?? [];
  const canRemoveMembers = organizationData?.is_billing_owner ?? false;

  const getDisplayName = (input: {
    first_name?: string | null;
    last_name?: string | null;
    name?: string | null;
    email?: string | null;
  }) => {
    const combined = [input.first_name, input.last_name].filter(Boolean).join(" ").trim();
    if (combined) {
      return combined;
    }
    if (input.name) {
      return input.name;
    }
    return input.email || t("organizationMenu.unknownUser", "Utilisateur");
  };

  const MenuSeparator = () => {
    return <DropdownMenuSeparator className="bg-gray-300 dark:bg-gray-500!" />;
  };

  const itemVariants = cva("", {
    variants: {
      variant: {
        default:
          "text-gray-600 dark:text-gray-200/90 focus:bg-gray-200/80 dark:focus:bg-gray-500/80 focus:text-gray-900 dark:focus:text-white",
        destructive: "text-red-500/80 focus:bg-red-500/80 focus:text-white",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  });

  const MenuDropdownItem = ({
    icon,
    label,
    variant,
    onClick,
  }: {
    icon: React.ReactNode;
    label: string;
    onClick?: () => void;
  } & VariantProps<typeof itemVariants>) => {
    return (
      <DropdownMenuItem className={cn(itemVariants({ variant }))} onClick={onClick}>
        <div className="flex flex-row items-center gap-2">
          {icon}
          {label}
        </div>
      </DropdownMenuItem>
    );
  };

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button
          aria-label="Organization menu"
          variant="ghost"
          className={twMerge(
            "flex items-center justify-start hover:bg-navbar-darker w-full h-auto pl-2 py-1.5 gap-1",
            isCollapsed && "justify-center px-2"
          )}
        >
          <Avatar className="size-7">
            <AvatarFallback>
              {organizationData?.organization?.name?.charAt(0).toUpperCase() ?? "O"}
            </AvatarFallback>
          </Avatar>
          {!isCollapsed && (
            <div className="flex flex-col items-start">
              <TypographyMuted className="text-gray-700 dark:text-gray-300/90 transition-all duration-300 ml-1 truncate font-medium overflow-hidden text-ellipsis">
                {organizationData?.organization?.name ||
                  t("organizationMenu.title", "Organisation")}
              </TypographyMuted>
              <TypographyMuted className="text-gray-500 dark:text-gray-400/90 transition-all duration-300 ml-1 text-xs truncate overflow-hidden text-ellipsis">
                {t("organizationMenu.memberCount", {
                  count: organizationData?.organization?.member_count ?? 0,
                })}
              </TypographyMuted>
            </div>
          )}
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent
        className="min-w-56 bg-navbar-background border-gray-300 dark:border-gray-600/50 p-1 rounded-lg text-gray-900 dark:text-white"
        side="right"
        align="end"
        sideOffset={-8}
      >
        <div className="flex flex-col gap-0.5 min-w-0 flex-1 px-2 py-1">
          <TypographyMuted className="font-bold text-gray-800 dark:text-gray-100 text-sm truncate">
            {organizationData?.organization?.name || t("organizationMenu.title", "Organisation")}
          </TypographyMuted>
          <TypographyMuted className="text-gray-500 dark:text-gray-300 text-xs truncate">
            {t("organizationMenu.memberCount", {
              count: organizationData?.organization?.member_count ?? 0,
            })}
          </TypographyMuted>
        </div>

        <MenuSeparator />

        <div className="max-h-64 overflow-y-auto px-2 py-1 space-y-2">
          <p className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">
            {t("organizationMenu.members", "Membres")}
          </p>
          {members.length === 0 ? (
            <p className="text-xs text-muted-foreground">
              {t("organizationMenu.noMembers", "Aucun membre")}
            </p>
          ) : (
            members.map((member) => (
              <div key={member.id} className="flex items-center justify-between gap-2">
                <div className="min-w-0 flex items-center gap-2">
                  <Avatar className="size-6">
                    <AvatarImage
                      src={member.avatar_url ?? undefined}
                      alt={member.name ?? "Avatar"}
                    />
                    <AvatarFallback>
                      {(member.name || member.email || "U").charAt(0).toUpperCase()}
                    </AvatarFallback>
                  </Avatar>
                  <div className="min-w-0">
                    <p className="text-xs font-medium truncate">
                      {getDisplayName({
                        first_name: member.first_name,
                        last_name: member.last_name,
                        name: member.name,
                        email: member.email,
                      })}
                    </p>
                    <p className="text-xs text-muted-foreground truncate">{member.email}</p>
                  </div>
                </div>
                {canRemoveMembers && member.id !== user.id && (
                  <Button
                    variant="ghost"
                    size="icon"
                    className="size-7 text-red-500 hover:text-red-600"
                    disabled={isRemovingMember}
                    onClick={() => {
                      const confirmed = window.confirm(
                        t("organizationMenu.removeConfirm", "Retirer ce membre de l'organisation ?")
                      );
                      if (!confirmed) return;
                      removeOrganizationMember(member.id);
                    }}
                  >
                    <UserMinus className="w-4 h-4" />
                  </Button>
                )}
              </div>
            ))
          )}
        </div>

        <MenuSeparator />

        <RouterLink to="/settings">
          <MenuDropdownItem
            icon={<SettingsIcon className="w-5 h-5" aria-hidden="true" />}
            label={t("userMenu.settings")}
            variant="default"
          />
        </RouterLink>

        <MenuDropdownItem
          icon={<LogOutIcon className="w-5 h-5" aria-hidden="true" />}
          label={t("userMenu.logout")}
          variant="destructive"
          onClick={logout}
        />

        <MenuSeparator />
        <div className="flex flex-row my-2 ml-1 items-center">
          <ThemeSwitcher />
        </div>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

export const SideNavigation = ({ isMobileMenuOpen }: { isMobileMenuOpen: boolean }) => {
  const isCollapsable = !isMobileMenuOpen;
  const [isCollapsed, setIsCollapsed] = useState(!isCollapsable);

  return (
    <nav
      aria-label="Main navigation"
      className={twMerge(
        "group isolate flex flex-col overflow-y-auto overflow-x-hidden bg-navbar-background transition-all duration-300",
        "fixed md:relative h-[calc(100vh-2rem)] md:h-screen z-50",
        isCollapsed ? "w-16" : "w-48",
        "md:flex",
        "transform md:transform-none",
        isMobileMenuOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"
      )}
    >
      <div className="relative flex flex-col items-center px-2 py-3 w-full">
        <RouterLink
          to="/"
          className={twMerge(
            "flex flex-col items-center gap-2 w-full",
            isCollapsed ? "justify-center" : ""
          )}
          aria-label="Home"
        >
          <img
            src={getXtabloIcon()}
            alt="Logo XTablo"
            className={twMerge(isCollapsed ? "w-8 h-8" : "w-16 h-16", "rounded-lg")}
          />
          <h1
            className={twMerge(
              "text-lg font-bold transition-all duration-300 text-gray-900 dark:text-white whitespace-nowrap",
              isCollapsed ? "w-0 h-0 opacity-0" : "w-auto opacity-100"
            )}
          >
            XTablo {isProd ? "" : isStaging ? "Staging" : "Dev"}
          </h1>
        </RouterLink>
        {isCollapsable && (
          <Button
            variant="ghost"
            size="icon"
            onClick={() => setIsCollapsed(!isCollapsed)}
            aria-label={isCollapsed ? "Expand navigation" : "Collapse navigation"}
            aria-expanded={!isCollapsed}
            className={twMerge(
              isCollapsed ? "relative" : "absolute top-2 right-2",
              "size-5 p-1",
              "text-gray-500 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white",
              "transition-all duration-300",
              "bg-navbar-background",
              "rounded-full shadow-md",
              "opacity-0 group-hover:opacity-100",
              "hover:scale-110"
            )}
          >
            {isCollapsed ? <PlusIcon aria-hidden="true" /> : <MinusIcon aria-hidden="true" />}
          </Button>
        )}
      </div>
      <MainNavigation isCollapsed={isCollapsed} />
      <div
        className={twMerge(
          "bg-navbar-background flex flex-col px-1 pb-1.5 w-full mt-auto gap-1",
          isCollapsed ? "pl-2.5 pr-3.5" : ""
        )}
      >
        <UserMenuPopover isCollapsed={isCollapsed} />
      </div>
    </nav>
  );
};

function getTabloIcon(color: string | null | undefined) {
  switch (color) {
    case "bg-blue-500":
      return Zap;
    case "bg-green-500":
      return Leaf;
    case "bg-purple-500":
      return Gem;
    case "bg-red-500":
      return Flame;
    case "bg-yellow-500":
      return Star;
    case "bg-indigo-500":
      return Compass;
    case "bg-pink-500":
      return Heart;
    case "bg-teal-500":
      return Waves;
    case "bg-orange-500":
      return Sun;
    case "bg-cyan-500":
      return Sparkles;
    default:
      return FolderIcon;
  }
}

function getTabloIconColor(_color: string | null | undefined): string {
  return "text-gray-700 dark:text-white";
}

function RecentProjectsSection() {
  const { t } = useTranslation("navigation");
  const location = useLocation();
  const { data: tablos } = useTablosList();
  const recentTablos = (tablos ?? []).slice(0, 4);

  if (recentTablos.length === 0) return null;

  return (
    <div className="px-2 pb-2">
      <Separator className="border-gray-300 dark:border-gray-300/20 mb-3" />
      <div className="px-2 mb-2">
        <span className="text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">
          {t("projects", "Projects")}
        </span>
      </div>
      <ul className="space-y-0.5">
        {recentTablos.map((tablo) => {
          const isActive = location.pathname === `/tablos/${tablo.id}`;
          const TabloIcon = getTabloIcon(tablo.color);
          const iconColor = getTabloIconColor(tablo.color);
          return (
            <li key={tablo.id}>
              <RouterLink
                to={`/tablos/${tablo.id}`}
                className={twMerge(
                  "flex items-center gap-2.5 px-2 py-1.5 rounded-lg text-sm transition-colors",
                  isActive
                    ? "bg-purple-100 dark:bg-purple-900/30 text-[#804EEC] dark:text-purple-300 font-semibold"
                    : "text-gray-500 dark:text-gray-300/90 hover:bg-navbar-darker hover:text-gray-900 dark:hover:text-white"
                )}
              >
                <span
                  className="w-6 h-6 rounded-full shrink-0 flex items-center justify-center border border-gray-400 dark:border-gray-500/50"
                  style={{ backgroundColor: tablo.color ?? "#6b7280" }}
                >
                  <TabloIcon className={twMerge("w-3.5 h-3.5", iconColor)} />
                </span>
                <span className="truncate flex-1">{tablo.name}</span>
              </RouterLink>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

export function MainNavigation({ isCollapsed }: { isCollapsed: boolean }) {
  const location = useLocation();
  const isReadOnly = useIsReadOnlyUser();
  const user = useUser();
  const { t } = useTranslation("navigation");
  const { mutate: createCheckout, isPending: checkoutPending } = useCreateCheckoutSession();
  const { data: organizationData } = useOrganization();

  const hasCompliantTeamPlan =
    organizationData?.active_subscription_plan === "annual" ||
    (organizationData?.active_subscription_plan === "team" &&
      organizationData.active_subscription_quantity >= organizationData.required_team_quantity);

  const shouldShowSoloUpsell =
    !user.is_temporary &&
    !!organizationData &&
    organizationData.required_plan === "team" &&
    !hasCompliantTeamPlan;

  type List<T> = T[];

  const navItems: List<
    | {
        path: string;
        label: string;
        icon: React.ReactNode;
        isDisabled?: boolean;
        isHorizontalBar?: never;
      }
    | {
        isHorizontalBar: boolean;
      }
  > = isReadOnly
    ? [
        {
          path: "/",
          label: t("home"),
          icon: <PanelsTopLeft className="w-5 h-5" />,
        },
        {
          path: "/planning",
          label: t("planning"),
          icon: <SquareKanban className="w-5 h-5" />,
        },
      ]
    : [
        {
          path: "/",
          label: t("home"),
          icon: <PanelsTopLeft className="w-5 h-5" />,
        },
        {
          path: "/kanban",
          label: t("kanban"),
          icon: <Kanban className="w-5 h-5" />,
          isDisabled: true,
        },
        {
          path: "/chantiers",
          label: t("chantiers"),
          icon: <ConstructionIcon className="w-5 h-5" />,
          isDisabled: true,
        },
        { isHorizontalBar: true },
        {
          path: "/tasks",
          label: t("tasks"),
          icon: <ListTodo className="w-5 h-5" />,
        },
        {
          path: "/tablos",
          label: t("tablos"),
          icon: <LayersIcon className="w-5 h-5" />,
        },
        { isHorizontalBar: true },
        {
          path: "/planning",
          label: t("planning"),
          icon: <SquareKanban className="w-5 h-5" />,
        },
        {
          path: "/chat",
          label: t("discussions"),
          icon: <MessageCircleIcon className="w-5 h-5" />,
        },
        {
          path: "/files",
          label: t("files", "Fichiers"),
          icon: <FolderIcon className="w-5 h-5" />,
        },
        // Notes feature temporarily hidden
        // {
        //   path: "/notes",
        //   label: t("notes"),
        //   icon: <FileTextIcon className="w-5 h-5" />,
        // },
      ];
  return (
    <nav className="flex flex-1 flex-col" aria-label="Primary navigation">
      <ul role="list" className={twMerge("grid py-3", isCollapsed ? "pl-2.5 pr-3" : "")}>
        {navItems.map((item, index) => {
          if ("isHorizontalBar" in item) {
            return (
              <li key={`horizontal-bar-${index}`} className="my-2">
                <Separator className="border-gray-300 dark:border-gray-300/20" />
              </li>
            );
          }

          const { path, label, icon, isDisabled } = item;
          const isActive = location.pathname === path;

          return !isDisabled ? (
            <li key={label}>
              <NavLink isActive={isActive}>
                <RouterLink
                  to={path}
                  className="w-full"
                  aria-label={isCollapsed ? label : undefined}
                >
                  <div
                    className={twMerge("flex items-center gap-x-2.5", isCollapsed ? "" : "pl-2")}
                  >
                    <span className="[&>svg]:w-6 [&>svg]:h-6">{icon}</span>
                    <TypographyLarge
                      className={twMerge(
                        "text-base transition-all duration-300 font-normal",
                        isActive
                          ? "text-[#804EEC] dark:text-purple-300"
                          : "text-gray-500 dark:text-gray-300/90",
                        isCollapsed ? "opacity-0 w-0 hidden" : "opacity-100"
                      )}
                    >
                      {label}
                    </TypographyLarge>
                  </div>
                </RouterLink>
              </NavLink>
            </li>
          ) : null;
        })}
      </ul>

      {/* Recent projects section */}
      {!isCollapsed && <RecentProjectsSection />}

      <ul role="list" className={twMerge("mt-auto grid py-1", isCollapsed ? "pl-2.5 pr-3" : "")}>
        {/* Solo upsell message */}
        {shouldShowSoloUpsell && !isCollapsed && (
          <li className="mb-2">
            <div
              className={twMerge(
                "mx-2 mb-2 p-3 rounded-lg border",
                "bg-linear-to-br from-purple-50 to-blue-50 dark:from-purple-950/20 dark:to-blue-950/20 border-purple-200 dark:border-purple-800"
              )}
            >
              <div className="flex items-start gap-2 mb-2">
                <Sparkles className="w-4 h-4 text-purple-600 dark:text-purple-400 shrink-0 mt-0.5" />
                <div className="flex-1 min-w-0">
                  <p className="text-xs font-medium text-purple-900 dark:text-purple-100">
                    Plan Teams
                  </p>
                  <p className="text-xs mt-0.5 text-purple-700 dark:text-purple-300">
                    Ajoutez des sièges Teams pour inviter des membres.
                  </p>
                </div>
              </div>
              <Button
                size="sm"
                onClick={() =>
                  createCheckout({
                    plan: "team",
                    successUrl: `${window.location.origin}?upgraded=true`,
                    cancelUrl: `${window.location.origin}?canceled=true`,
                  })
                }
                disabled={checkoutPending}
                className="w-full h-7 text-xs gap-1 bg-linear-to-r from-purple-500 to-blue-500 hover:from-purple-600 hover:to-blue-600"
              >
                {checkoutPending ? (
                  "..."
                ) : (
                  <>
                    <CreditCard className="w-3 h-3" />
                    Passer au plan Team
                  </>
                )}
              </Button>
            </div>
          </li>
        )}
        {/* <li>
          <NavLink isActive={location.pathname === "/support"}>
            <RouterLink
              to="/support"
              className={twMerge("w-full", isCollapsed ? "" : "pl-2")}
              aria-label={isCollapsed ? "Support" : undefined}
            >
              <div className="flex items-center gap-x-2">
                <Icon aria-hidden="true">
                  <HelpCircleIcon className="w-5 h-5" />
                </Icon>
                <span
                  className={twMerge(
                    "text-sm transition-all duration-300",
                    isCollapsed ? "opacity-0 w-0 hidden" : "opacity-100"
                  )}
                >
                  Support
                </span>
              </div>
            </RouterLink>
          </NavLink>
        </li> */}
        <li>
          <NavLink isActive={location.pathname === "/feedback"}>
            <RouterLink
              to="/feedback"
              className="w-full"
              aria-label={isCollapsed ? "Feedback" : undefined}
            >
              <div className={twMerge("flex items-center gap-x-2.5", isCollapsed ? "" : "pl-2")}>
                <span className="[&>svg]:w-6 [&>svg]:h-6">
                  <SendIcon aria-hidden="true" />
                </span>
                <TypographyLarge
                  className={twMerge(
                    "text-base transition-all duration-300 font-normal",
                    location.pathname === "/feedback"
                      ? "text-gray-900 dark:text-white"
                      : "text-gray-500 dark:text-gray-300/90",
                    isCollapsed ? "opacity-0 w-0 hidden" : "opacity-100"
                  )}
                >
                  {t("feedback")}
                </TypographyLarge>
              </div>
            </RouterLink>
          </NavLink>
        </li>
        <li className="my-2">
          <Separator className="border-gray-300 dark:border-gray-300/20" />
        </li>
      </ul>
    </nav>
  );
}
