import { Link } from '@tanstack/react-router';
import { useEffect, useRef, useState } from 'react';
import type { LucideIcon } from 'lucide-react';
import {
  Home, Music, Disc3, Users, Tag, Compass,
  Terminal, ShieldAlert,
  Zap,
  Settings, Sparkles, X,
} from 'lucide-react';

interface NavItem {
  to: string;
  icon: LucideIcon;
  label: string;
  exact?: boolean;
}

interface NavGroup {
  label: string;
  items: NavItem[];
}

const NAV_GROUPS: NavGroup[] = [
  {
    label: 'Workspace',
    items: [
      { to: '/', icon: Home, label: 'Home', exact: true },
      { to: '/tracks', icon: Music, label: 'Songs' },
      { to: '/albums', icon: Disc3, label: 'Albums' },
      { to: '/artists', icon: Users, label: 'Artists' },
      { to: '/genres', icon: Tag, label: 'Genres' },
    ],
  },
  {
    label: 'AI',
    items: [
      { to: '/vibe', icon: Zap, label: 'Vibe' },
      { to: '/recommendations', icon: Compass, label: 'Found' },
    ],
  },
  {
    label: 'Infrastructure',
    items: [
      { to: '/jobs', icon: Terminal, label: 'Jobs' },
      { to: '/quarantine', icon: ShieldAlert, label: 'Quarantine' },
    ],
  },
  {
    label: 'Settings',
    items: [
      { to: '/settings', icon: Settings, label: 'Settings' },
    ],
  },
];

const base =
  'group relative flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs w-full transition-all duration-100';
const inactive = 'text-secondary hover:bg-surface0 hover:text-text';
const active =
  'bg-accent/10 text-accent font-medium ' +
  "before:content-[''] before:absolute before:left-0 before:top-1 before:bottom-1 before:w-0.5 before:rounded-full before:bg-accent";

interface NavRailProps {
  open: boolean;
  onClose: () => void;
}

export function NavRail({ open, onClose }: NavRailProps) {
  const [desktop, setDesktop] = useState(false);
  const drawerRef = useRef<HTMLElement>(null);
  const closeRef = useRef<HTMLButtonElement>(null);
  useEffect(() => {
    const query = window.matchMedia('(min-width: 1024px)');
    const update = () => setDesktop(query.matches);
    update();
    query.addEventListener('change', update);
    return () => query.removeEventListener('change', update);
  }, []);
  useEffect(() => {
    if (open && !desktop) closeRef.current?.focus();
  }, [open, desktop]);
  useEffect(() => {
    if (!open || desktop || !drawerRef.current) return;
    const previous = document.activeElement as HTMLElement | null;
    const trap = (event: KeyboardEvent) => {
      if (event.key !== 'Tab' || !drawerRef.current) return;
      const focusable = [...drawerRef.current.querySelectorAll<HTMLElement>(
        'a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])'
      )].filter((element) => !element.hasAttribute('hidden'));
      if (focusable.length === 0) return;
      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      if (event.shiftKey && document.activeElement === first) {
        event.preventDefault(); last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault(); first.focus();
      }
    };
    document.addEventListener('keydown', trap);
    return () => {
      document.removeEventListener('keydown', trap);
      previous?.focus();
    };
  }, [open, desktop]);

  // Do not leave an off-screen mobile drawer in the tab order. The desktop
  // rail remains mounted independently of the drawer state.
  if (!desktop && !open) return null;
  return (
    <>
      {open && (
        <button
          type="button"
          className="absolute inset-0 z-30 bg-black/60 lg:hidden"
          aria-label="Close navigation"
          onClick={onClose}
        />
      )}
      <aside
        ref={drawerRef}
        aria-label="Main navigation"
        aria-modal={!desktop || undefined}
        role={desktop ? undefined : 'dialog'}
        className={`absolute inset-y-0 left-0 z-40 flex w-72 max-w-[85vw] flex-col overflow-y-auto border-r border-border bg-bg1 shadow-2xl transition-transform duration-200 lg:relative lg:z-auto lg:w-48 lg:max-w-none lg:translate-x-0 lg:shadow-none ${
          open ? 'translate-x-0' : '-translate-x-full'
        }`}
      >
      {/* App branding */}
      <div className="flex items-center gap-2 px-3 py-2.5 border-b border-border">
        <span className="flex h-6 w-6 items-center justify-center rounded-md bg-accent text-on-accent">
          <Sparkles size={14} />
        </span>
        <span className="text-sm font-semibold text-text tracking-tight">muzick</span>
        <button
          ref={closeRef}
          type="button"
          onClick={onClose}
          className="ml-auto rounded-md p-2 text-muted hover:bg-surface0 hover:text-text lg:hidden"
          aria-label="Close navigation"
        >
          <X size={18} />
        </button>
      </div>

      {/* Navigation */}
      <nav className="flex-1 px-2 space-y-4 pb-3 pt-3">
        {NAV_GROUPS.map((group) => (
          <div key={group.label}>
            <div className="px-3 mb-1 text-[10px] font-semibold uppercase tracking-[0.1em] text-disabled">
              {group.label}
            </div>
            <ul className="space-y-0.5">
              {group.items.map(({ to, icon: Icon, label, exact }) => (
                <li key={to}>
                  <Link
                    to={to}
                    activeOptions={{ exact: exact ?? false }}
                    activeProps={{ className: `${base} ${active}` }}
                    inactiveProps={{ className: `${base} ${inactive}` }}
                    onClick={onClose}
                  >
                    <Icon size={15} className="flex-none transition-transform group-hover:scale-110" />
                    <span className="truncate">{label}</span>
                  </Link>
                </li>
              ))}
            </ul>
          </div>
        ))}
      </nav>

      {/* Footer */}
      <div className="px-3 py-2 text-[10px] text-disabled border-t border-border">
        muzick · v0.1
      </div>
      </aside>
    </>
  );
}
