import {
  BarChart3,
  BookOpen,
  ChevronRight,
  FilePenLine,
  LayoutDashboard,
  LogOut,
  Menu,
  ShieldCheck,
  UserRound,
  Users,
  X,
} from "lucide-react";
import { AnimatePresence } from "framer-motion";
import { useState } from "react";
import { Link, NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
import { useSession } from "../store/session";
import { Button } from "../../shared/ui/Button";
import { Badge } from "../../shared/ui/Badge";
import { DstuLogo } from "../../shared/ui/DstuLogo";
import { cn } from "../../shared/lib/cn";
import { ThemeToggle } from "../../shared/ui/ThemeToggle";
import { PageTransition } from "../../shared/ui/PageTransition";

const roleLabels = {
  user: "Пользователь",
  editor: "Редактор",
  moderator: "Модератор",
  admin: "Администратор",
};

const navItems = [
  { to: "/cabinet", label: "Обзор", icon: LayoutDashboard, roles: ["user", "editor", "moderator", "admin"], end: true },
  { to: "/cabinet/profile", label: "Профиль", icon: UserRound, roles: ["user", "editor", "moderator", "admin"] },
  { to: "/cabinet/editor", label: "Мои материалы", icon: FilePenLine, roles: ["editor", "admin"] },
  { to: "/cabinet/moderation", label: "Модерация", icon: ShieldCheck, roles: ["moderator", "admin"] },
  { to: "/cabinet/admin", label: "Управление", icon: Users, roles: ["admin"] },
];

export function CabinetLayout() {
  const [open, setOpen] = useState(false);
  const user = useSession((state) => state.user);
  const logout = useSession((state) => state.logout);
  const switchRole = useSession((state) => state.switchRole);
  const navigate = useNavigate();
  const location = useLocation();

  const visibleNav = navItems.filter((item) => item.roles.includes(user.role));

  const navigation = (
    <>
      <div className="flex h-18 items-center justify-between border-b border-white/10 px-5">
        <Link to="/" className="flex items-center gap-3 text-white" onClick={() => setOpen(false)}>
          <DstuLogo className="size-9" />
          <span className="font-serif text-lg">ДГТУ МЕДИА</span>
        </Link>
        <button
          className="grid size-10 place-items-center rounded-md text-white/80 hover:bg-white/10 hover:text-white lg:hidden"
          onClick={() => setOpen(false)}
          aria-label="Закрыть меню"
        >
          <X className="size-5" />
        </button>
      </div>
      <nav className="flex-1 space-y-1 p-4">
        {visibleNav.map(({ to, label, icon: Icon, end }) => (
          <NavLink
            key={to}
            to={to}
            end={end}
            onClick={() => setOpen(false)}
            className={({ isActive }) =>
              cn(
                "flex items-center gap-3 rounded-md px-3 py-2.5 text-sm font-semibold transition",
                isActive
                  ? "bg-dstu-menu-accent text-dstu-menu"
                  : "text-white/70 hover:bg-white/10 hover:text-white",
              )
            }
          >
            <Icon className="size-4.5" />
            {label}
          </NavLink>
        ))}
      </nav>
      <div className="border-t border-white/10 p-4">
        <button
          onClick={() => {
            logout();
            navigate("/");
          }}
          className="flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-sm font-semibold text-white/70 hover:bg-white/10 hover:text-white"
        >
          <LogOut className="size-4.5" /> Выйти
        </button>
      </div>
    </>
  );

  return (
    <div className="min-h-screen bg-paper lg:grid lg:grid-cols-[clamp(14rem,20vw,18rem)_minmax(0,1fr)]">
      <aside className="hidden min-h-screen flex-col bg-dstu-menu text-white lg:flex">{navigation}</aside>
      {open && (
        <>
          <button className="fixed inset-0 z-40 bg-ink/35 lg:hidden" onClick={() => setOpen(false)} aria-label="Закрыть меню" />
          <aside className="fixed inset-y-0 left-0 z-50 flex w-[min(86vw,22rem)] flex-col bg-dstu-menu text-white lg:hidden">
            {navigation}
          </aside>
        </>
      )}

      <div className="min-w-0">
        <header className="sticky top-0 z-30 flex h-18 items-center gap-4 border-b border-line bg-paper/95 px-4 backdrop-blur sm:px-6">
          <button className="grid size-10 place-items-center rounded-md lg:hidden" onClick={() => setOpen(true)} aria-label="Открыть меню">
            <Menu className="size-5" />
          </button>
          <div className="hidden items-center gap-2 text-sm text-muted sm:flex">
            <Link to="/cabinet">Кабинет</Link>
            {location.pathname !== "/cabinet" && (
              <>
                <ChevronRight className="size-4" />
                <span className="text-ink">Раздел</span>
              </>
            )}
          </div>
          <div className="ml-auto flex items-center gap-3">
            <ThemeToggle />
            <label className="hidden text-xs text-muted md:block">
              Тестовая роль
              <select
                value={user.role}
                onChange={(event) => {
                  switchRole(event.target.value);
                  navigate("/cabinet");
                }}
                className="ml-2 rounded-md border border-line bg-surface px-2 py-1.5 text-ink dark:[color-scheme:dark]"
              >
                <option value="user">Пользователь</option>
                <option value="editor">Редактор</option>
                <option value="moderator">Модератор</option>
                <option value="admin">Администратор</option>
              </select>
            </label>
            <div className="text-right">
              <p className="text-sm font-semibold">{user.name}</p>
              <Badge className="mt-1">{roleLabels[user.role]}</Badge>
            </div>
          </div>
        </header>
        <main className="page-shell-wide overflow-x-clip py-4 sm:py-6 lg:py-8">
          <AnimatePresence mode="wait" initial={false}>
            <PageTransition key={location.pathname} routeKey={location.pathname}>
              <Outlet />
            </PageTransition>
          </AnimatePresence>
        </main>
      </div>
    </div>
  );
}
