"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { Check, ChevronDown, Search, X } from "lucide-react";
import { Logo } from "@/components/logo";
import { ADMIN_MENU, type MenuGroup } from "@/components/admin/menu";
import type { Role } from "@/lib/types";
import { cn, initials } from "@/lib/utils";

function visibleMenu(role: Role): MenuGroup[] {
  return ADMIN_MENU.map((group) => ({
    ...group,
    items: group.items.filter((item) =>
      item.href
        ? !item.roles || item.roles.includes(role)
        : role === "ADMIN",
    ),
  })).filter((group) => {
    if (group.href || group.soon) return !group.roles || group.roles.includes(role);
    return group.items.length > 0;
  });
}

function ParityMark() {
  return (
    <span
      title="Isi menu ini sudah disamakan dengan OpenSID lama"
      className="inline-flex shrink-0 items-center gap-1 rounded bg-emerald-500/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-emerald-400"
    >
      <Check className="h-2.5 w-2.5" />
      Sama
    </span>
  );
}

export function AdminSidebar({
  role,
  nama,
  mobileOpen,
  onClose,
}: {
  role: Role;
  nama: string;
  mobileOpen: boolean;
  onClose: () => void;
}) {
  const pathname = usePathname();
  const groups = useMemo(() => visibleMenu(role), [role]);
  const [query, setQuery] = useState("");
  const [open, setOpen] = useState<string[]>([]);

  const activeGroup = groups.find(
    (group) =>
      group.href === pathname ||
      group.items.some(
        (item) => item.href && (pathname === item.href || pathname.startsWith(`${item.href}/`)),
      ),
  )?.label;

  useEffect(() => {
    if (activeGroup) {
      setOpen((current) => (current.includes(activeGroup) ? current : [...current, activeGroup]));
    }
  }, [activeGroup]);

  const kata = query.trim().toLowerCase();
  const filtered = kata
    ? groups
        .map((group) => ({
          ...group,
          items: group.items.filter((item) => item.label.toLowerCase().includes(kata)),
        }))
        .filter((group) => group.href || group.soon || group.items.length > 0)
    : groups;

  function isActive(href: string) {
    const path = href.split("?")[0];
    return pathname === path || pathname.startsWith(`${path}/`);
  }

  const content = (
    <div className="flex h-full flex-col bg-sidebar text-sidebar-foreground">
      <div className="flex h-16 items-center justify-between border-b border-white/10 px-5">
        <Link href="/admin" className="flex items-center gap-3" onClick={onClose}>
          <Logo className="h-12 w-auto" />
          <div className="leading-tight">
            <div className="text-sm font-bold tracking-tight text-white">Core Mulyadadi</div>
            <div className="text-[10px] uppercase tracking-wider text-sidebar-muted">
              Panel Administrasi
            </div>
          </div>
        </Link>
        <button
          type="button"
          onClick={onClose}
          className="rounded-lg p-1.5 text-sidebar-muted hover:bg-white/10 hover:text-white lg:hidden"
          aria-label="Tutup menu"
        >
          <X className="h-5 w-5" />
        </button>
      </div>

      <div className="border-b border-white/10 px-3 py-3">
        <div className="relative">
          <Search className="absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-sidebar-muted" />
          <input
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            placeholder="Cari menu…"
            className="w-full rounded-lg border border-white/10 bg-white/5 py-1.5 pl-8 pr-3 text-xs text-white placeholder:text-sidebar-muted/70 focus:border-[hsl(var(--brand-accent)/0.5)] focus:outline-none"
          />
        </div>
      </div>

      <nav className="flex-1 space-y-1 overflow-y-auto px-3 py-4">
        {filtered.map((group) => {
          if (group.href) {
            const active = isActive(group.href);
            return (
              <Link
                key={group.label}
                href={group.href}
                onClick={onClose}
                className={cn(
                  "flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm transition-colors",
                  active
                    ? "bg-sidebar-accent font-semibold text-white"
                    : "text-sidebar-muted hover:bg-white/5 hover:text-white",
                )}
              >
                <group.icon
                  className={cn("h-4 w-4 shrink-0", active ? "text-brand-accent" : "text-sidebar-muted")}
                />
                <span className="flex-1 truncate">{group.label}</span>
                {group.parity && <ParityMark />}
              </Link>
            );
          }

          if (group.soon) {
            return (
              <div
                key={group.label}
                className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-sidebar-muted/60"
              >
                <group.icon className="h-4 w-4 shrink-0 text-sidebar-muted/60" />
                <span className="flex-1 truncate">{group.label}</span>
                <span className="rounded bg-white/5 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-sidebar-muted/70">
                  Segera
                </span>
              </div>
            );
          }

          const expanded = kata ? true : open.includes(group.label);
          return (
            <div key={group.label}>
              <button
                type="button"
                onClick={() =>
                  setOpen((current) =>
                    current.includes(group.label)
                      ? current.filter((label) => label !== group.label)
                      : [...current, group.label],
                  )
                }
                className={cn(
                  "flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm transition-colors",
                  activeGroup === group.label
                    ? "font-semibold text-white"
                    : "text-sidebar-muted hover:bg-white/5 hover:text-white",
                )}
                aria-expanded={expanded}
              >
                <group.icon
                  className={cn(
                    "h-4 w-4 shrink-0",
                    activeGroup === group.label ? "text-brand-accent" : "text-sidebar-muted",
                  )}
                />
                <span className="flex-1 truncate">{group.label}</span>
                {group.parity && <ParityMark />}
                <ChevronDown
                  className={cn(
                    "h-3.5 w-3.5 shrink-0 transition-transform",
                    expanded && "rotate-180",
                  )}
                />
              </button>

              {expanded && (
                <div className="ml-[1.35rem] space-y-0.5 border-l border-white/10 pl-3 pt-0.5">
                  {group.items.map((item) => {
                    if (!item.href) {
                      return (
                        <div
                          key={item.label}
                          className="flex items-center justify-between gap-2 rounded-md px-2.5 py-1.5 text-[13px] text-sidebar-muted/60"
                        >
                          <span className="truncate">{item.label}</span>
                          <span className="rounded bg-white/5 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-sidebar-muted/70">
                            Segera
                          </span>
                        </div>
                      );
                    }
                    const active =
                      isActive(item.href) &&
                      !group.items.some(
                        (sib) =>
                          sib.href &&
                          sib.href !== item.href &&
                          sib.href.split("?")[0].length >
                            item.href!.split("?")[0].length &&
                          isActive(sib.href),
                      );
                    return (
                      <Link
                        key={item.label}
                        href={item.href}
                        onClick={onClose}
                        className={cn(
                          "flex items-center gap-2 rounded-md px-2.5 py-1.5 text-[13px] transition-colors",
                          active
                            ? "bg-sidebar-accent font-semibold text-white"
                            : "text-sidebar-muted hover:bg-white/5 hover:text-white",
                        )}
                      >
                        <span className="min-w-0 flex-1 truncate">{item.label}</span>
                        {item.parity && <ParityMark />}
                      </Link>
                    );
                  })}
                </div>
              )}
            </div>
          );
        })}

        {!filtered.length && (
          <p className="px-3 py-6 text-center text-xs text-sidebar-muted">
            Menu tidak ditemukan.
          </p>
        )}
      </nav>

      <div className="border-t border-white/10 p-4">
        <div className="flex items-center gap-3 rounded-lg bg-white/5 p-3">
          <div className="flex h-9 w-9 items-center justify-center rounded-full bg-brand-gradient text-xs font-bold text-white">
            {initials(nama)}
          </div>
          <div className="min-w-0">
            <div className="truncate text-sm font-semibold text-white">{nama}</div>
            <div className="text-[10px] uppercase tracking-wider text-sidebar-muted">
              {role}
            </div>
          </div>
        </div>
      </div>
    </div>
  );

  return (
    <>
      <aside className="fixed inset-y-0 left-0 z-30 hidden w-64 lg:block">{content}</aside>
      {mobileOpen && (
        <div className="fixed inset-0 z-50 lg:hidden">
          <div
            className="absolute inset-0 bg-slate-950/60 backdrop-blur-sm"
            onClick={onClose}
          />
          <div className="absolute inset-y-0 left-0 w-72 shadow-2xl">{content}</div>
        </div>
      )}
    </>
  );
}
