"use client";

import { useEffect } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
  LayoutDashboard,
  Send,
  Users,
  Receipt,
  Bell,
  UserCircle,
  Settings,
  LifeBuoy,
  Ticket,
  X,
  type LucideIcon,
} from "lucide-react";
import { Logo } from "@/components/common/Logo";
import { CouponSlider } from "@/components/app/CouponSlider";
import { useNotifications } from "@/hooks/useNotifications";
import { useTranslation } from "@/hooks/useTranslation";
import { cn } from "@/lib/utils";

interface NavItem {
  href: string;
  labelKey: string;
  icon: LucideIcon;
}

const NAV: NavItem[] = [
  { href: "/dashboard", labelKey: "app.nav.dashboard", icon: LayoutDashboard },
  { href: "/send", labelKey: "app.nav.send", icon: Send },
  { href: "/recipients", labelKey: "app.nav.recipients", icon: Users },
  { href: "/transactions", labelKey: "app.nav.transactions", icon: Receipt },
  { href: "/notifications", labelKey: "app.nav.notifications", icon: Bell },
  { href: "/profile", labelKey: "app.nav.profile", icon: UserCircle },
  { href: "/settings", labelKey: "app.nav.settings", icon: Settings },
  { href: "/coupons", labelKey: "app.nav.coupons", icon: Ticket },
  { href: "/help", labelKey: "app.nav.help", icon: LifeBuoy },
];

interface Props {
  open: boolean;
  onClose: () => void;
}

export function AppSidebar({ open, onClose }: Props) {
  const pathname = usePathname();
  const { t, dir } = useTranslation();
  const { unreadCount } = useNotifications();

  // Below 1440px it's a drawer — auto-close on navigation. At 1440px+ it's a
  // persistent panel the user folds manually, so a route change shouldn't close it.
  useEffect(() => {
    if (open && !window.matchMedia("(min-width: 1440px)").matches) onClose();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pathname]);

  // Below 1440px it's an overlay drawer, so scroll needs locking while open. At
  // 1440px+ it's a persistent panel that pushes content — page scroll is unaffected there.
  useEffect(() => {
    if (!open || window.matchMedia("(min-width: 1440px)").matches) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = prev;
    };
  }, [open]);

  const slideClosed = dir === "rtl" ? "translate-x-full" : "-translate-x-full";

  return (
    <>
      <div
        className={cn(
          "fixed inset-0 z-40 bg-slate-900/60 backdrop-blur-md transition-opacity duration-300 min-[1440px]:hidden",
          open ? "opacity-100" : "pointer-events-none opacity-0",
        )}
        onClick={onClose}
        aria-hidden
      />

      <aside
        aria-label={t("app.sidebar.primaryLabel")}
        className={cn(
          "fixed inset-y-0 start-0 z-50 flex h-screen w-full flex-col overflow-hidden border-e border-slate-200/70 bg-white shadow-elevated transition-transform duration-300 ease-snappy dark:border-slate-800/70 dark:bg-slate-950 sm:w-72 min-[1440px]:sticky min-[1440px]:top-0 min-[1440px]:w-full min-[1440px]:translate-x-0 min-[1440px]:shadow-none",
          open ? "translate-x-0" : slideClosed,
        )}
      >
        <div className="flex h-16 items-center justify-between border-b border-slate-200/70 px-5 dark:border-slate-800/70">
          <Logo />
          <button
            type="button"
            onClick={onClose}
            aria-label={t("app.sidebar.closeMenu")}
            className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-slate-200 text-slate-600 dark:border-slate-700 dark:text-slate-300 min-[1440px]:hidden"
          >
            <X className="h-4 w-4" />
          </button>
        </div>

        <nav className="flex flex-1 flex-col gap-1 overflow-y-auto p-4">
          {NAV.map((item) => {
            const active =
              item.href === "/dashboard"
                ? pathname === "/dashboard"
                : pathname.startsWith(item.href);
            const Icon = item.icon;
            const showBadge = item.href === "/notifications" && unreadCount > 0;
            return (
              <Link
                key={item.href}
                href={item.href}
                aria-current={active ? "page" : undefined}
                className={cn(
                  "group flex items-center gap-3 rounded-2xl px-3.5 py-2.5 text-sm font-medium transition-all duration-200",
                  active
                    ? "bg-brand-50 text-brand-700 shadow-soft dark:bg-brand-500/15 dark:text-brand-300"
                    : "text-slate-600 hover:bg-slate-100 hover:text-slate-900 dark:text-slate-300 dark:hover:bg-slate-800/60 dark:hover:text-white",
                )}
              >
                <Icon
                  className={cn(
                    "h-[18px] w-[18px] shrink-0 transition-transform duration-200 group-hover:scale-110",
                    active ? "text-brand-600 dark:text-brand-300" : "text-slate-400",
                  )}
                />
                <span className="flex-1">{t(item.labelKey)}</span>
                {showBadge && (
                  <span className="inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-rose-500 px-1.5 text-2xs font-bold text-white">
                    {unreadCount > 9 ? "9+" : unreadCount}
                  </span>
                )}
              </Link>
            );
          })}
        </nav>

        <CouponSlider />

        <div className="border-t border-slate-200/70 p-4 dark:border-slate-800/70">
          <div className="rounded-2xl bg-gradient-to-br from-brand-500/10 via-accent-500/5 to-transparent p-4 dark:from-brand-500/15">
            <p className="text-xs font-semibold uppercase tracking-wider text-brand-700 dark:text-brand-300">
              {t("app.sidebar.tipTitle")}
            </p>
            <p className="mt-1 text-xs leading-relaxed text-slate-600 dark:text-slate-300">
              {t("app.sidebar.tipBody")}
            </p>
          </div>
        </div>
      </aside>
    </>
  );
}
