"use client";

import { useAuth } from "@/components/providers";
import { GlobalSyncStatus } from "@/components/global-sync-status";
import { useFlagsConfiguracion } from "@/hooks/use-flags-configuracion";
import type { FlagsConfiguracion } from "@/lib/api";
import { TenantSwitcher } from "@/components/tenant-switcher";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
import { APP_VERSION_LABEL } from "@/lib/version";
import {
  BarChart3,
  Building2,
  Car,
  ClipboardList,
  FileSpreadsheet,
  History,
  LayoutGrid,
  LogOut,
  Menu,
  Network,
  Package,
  Plus,
  Search,
  Settings,
  Shield,
  SlidersHorizontal,
  Wrench,
  Users,
  X,
} from "lucide-react";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useState, type FormEvent, type ReactNode } from "react";

const mainNavigation = [
  { href: "/dashboard", label: "Resumen", icon: LayoutGrid },
  { href: "/dashboard/ots", label: "Recepciones", icon: ClipboardList },
  { href: "/dashboard/clientes", label: "Clientes", icon: Users },
  { href: "/dashboard/vehiculos", label: "Vehículos", icon: Car },
  { href: "/dashboard/mecanicos", label: "Mecánicos", icon: Wrench, flag: "usaMecanicos" },
  { href: "/dashboard/historial", label: "Historial", icon: History, flag: "usaHistorial" },
  { href: "/dashboard/catalogos", label: "Catálogos", icon: Settings },
  {
    href: "/dashboard/cargas-masivas",
    label: "Cargas masivas",
    icon: FileSpreadsheet,
    flag: "usaCargasMasivas",
  },
] as const;

const secondaryNavigation = [
  {
    href: "/dashboard/productos",
    label: "Productos",
    icon: Package,
    permission: "productos",
  },
  {
    href: "/dashboard/reportes",
    label: "Reportes",
    icon: BarChart3,
    permission: "reportes",
    flag: "usaReportes",
  },
  {
    href: "/dashboard/usuarios",
    label: "Usuarios",
    icon: Shield,
    permission: "usuarios",
  },
  {
    href: "/dashboard/tiendas",
    label: "Tiendas",
    icon: Building2,
    permission: "usuarios",
  },
  {
    href: "/dashboard/configuracion",
    label: "Configuración",
    icon: SlidersHorizontal,
    // Array, no un solo modulo: "configuracion" se partio en 5 permisos
    // granulares (uno por grupo) -- el boton de nav se muestra si el
    // usuario puede leer AL MENOS UNO, la pantalla decide adentro que
    // secciones mostrarle.
    permission: [
      "configuracion.facturacion",
      "configuracion.inventario",
      "configuracion.productos",
      "configuracion.tiendas",
      "configuracion.notificaciones",
      "configuracion.operacion",
    ],
  },
] as const;

// Superficie de PLATAFORMA, no de un tenant en particular — gateada por
// isPlatformAdmin (rolPlataforma), nunca por canRead/permissions (esos son
// permisos LOCALES de un tenant, no tienen nada que ver con administrar
// tenants).
const platformNavigation = [
  {
    href: "/dashboard/administracion/clientes",
    label: "Clientes (plataforma)",
    icon: Network,
  },
] as const;

// Cinco destinos en la barra inferior: los que se usan todos los días. Las
// etiquetas son de una sola palabra para que entren sin cortarse en un celular
// de 360px de ancho.
const mobileNavigation = [
  { href: "/dashboard", label: "Inicio", icon: LayoutGrid },
  { href: "/dashboard/ots", label: "Recepciones", icon: ClipboardList },
  { href: "/dashboard/ots/nueva", label: "Nueva", icon: Plus, primary: true },
  { href: "/dashboard/clientes", label: "Clientes", icon: Users },
  { href: "/dashboard/historial", label: "Historial", icon: History, flag: "usaHistorial" },
] as const;

/*
 * Gana la coincidencia más específica, no la primera de la lista.
 *
 * Antes, estando en /dashboard/ots/nueva el encabezado decía "Resumen": la
 * búsqueda devolvía el primer elemento cuyo href fuera prefijo de la ruta, y
 * "/dashboard" es prefijo de todo. Ordenar por largo de href antes de buscar lo
 * resuelve para cualquier ruta futura.
 */
function routeLabel(pathname: string): string {
  const allItems = [...mainNavigation, ...secondaryNavigation, ...platformNavigation];
  const match = [...allItems]
    .sort((a, b) => b.href.length - a.href.length)
    .find((item) => pathname === item.href || pathname.startsWith(`${item.href}/`));
  return match?.label || "Operación";
}

function isRouteActive(pathname: string, href: string): boolean {
  if (href === "/dashboard") return pathname === href;
  return pathname === href || pathname.startsWith(`${href}/`);
}

function roleLabel(rol: unknown): string {
  const raw = String(rol || "operativo").replace(/_/g, " ");
  return raw.charAt(0).toUpperCase() + raw.slice(1);
}

type NavItem = {
  href: string;
  label: string;
  icon: typeof LayoutGrid;
  permission?: string | readonly string[];
  flag?: keyof FlagsConfiguracion;
};

function puedeVerNavItem(permission: string | readonly string[] | undefined, canRead: (module: string) => boolean): boolean {
  if (!permission) return true;
  if (Array.isArray(permission)) return permission.some((modulo) => canRead(modulo));
  return canRead(permission as string);
}

/*
 * El estado activo se marca con fondo suave y texto en el azul de acento, no
 * con un bloque negro. Es más tranquilo y deja claro que es una selección y no
 * un botón.
 */
function NavLink({
  item,
  pathname,
  onNavigate,
}: {
  item: NavItem;
  pathname: string;
  onNavigate?: () => void;
}) {
  const active = isRouteActive(pathname, item.href);

  return (
    <Link
      href={item.href}
      onClick={onNavigate}
      aria-current={active ? "page" : undefined}
      className={cn(
        "flex min-h-[44px] items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-[color,background-color,transform] duration-150 active:scale-[0.97]",
        active
          ? "bg-primary-soft text-primary"
          : "text-muted-foreground [@media(hover:hover)]:hover:bg-muted [@media(hover:hover)]:hover:text-foreground",
      )}
    >
      <item.icon
        className={cn("h-5 w-5 shrink-0", active ? "text-primary" : "text-subtle-foreground")}
      />
      <span className="truncate">{item.label}</span>
    </Link>
  );
}

function NavGroup({
  title,
  items,
  pathname,
  onNavigate,
}: {
  title: string;
  items: readonly NavItem[];
  pathname: string;
  onNavigate?: () => void;
}) {
  if (items.length === 0) return null;

  return (
    <div className="mt-6 first:mt-0">
      <p className="eyebrow px-3 pb-2">{title}</p>
      <nav className="space-y-0.5">
        {items.map((item) => (
          <NavLink key={item.href} item={item} pathname={pathname} onNavigate={onNavigate} />
        ))}
      </nav>
    </div>
  );
}

function UserCard({ compact = false }: { compact?: boolean }) {
  const { user, logout } = useAuth();

  return (
    <div className="border-t border-border pt-4">
      <div className="flex items-center gap-3 px-3">
        <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-sm font-semibold text-muted-foreground">
          {(user?.nombre || "U").charAt(0).toUpperCase()}
        </span>
        <div className="min-w-0 flex-1">
          <p className="truncate text-sm font-semibold text-foreground">
            {user?.nombre || "Usuario"}
          </p>
          <p className="truncate text-xs text-muted-foreground">{roleLabel(user?.rol)}</p>
        </div>
      </div>

      <Button
        variant="ghost"
        onClick={() => logout()}
        className="mt-2 w-full justify-start px-3 text-muted-foreground hover:text-foreground"
      >
        <LogOut className="h-5 w-5" />
        Cerrar sesión
      </Button>

      {!compact ? (
        <p className="px-3 pt-2 text-xs text-subtle-foreground">MBtaller {APP_VERSION_LABEL}</p>
      ) : null}
    </div>
  );
}

export function DashboardShell({ children }: { children: ReactNode }) {
  const pathname = usePathname();
  const router = useRouter();
  const { canRead, isPlatformAdmin } = useAuth();
  const flags = useFlagsConfiguracion();
  const [menuOpen, setMenuOpen] = useState(false);
  const [quickSearch, setQuickSearch] = useState("");

  const flagActivo = (item: { flag?: keyof FlagsConfiguracion }) => !item.flag || flags[item.flag];
  const visibleMain = (mainNavigation as readonly NavItem[]).filter(flagActivo);
  const visibleSecondary = (secondaryNavigation as readonly NavItem[]).filter(
    (item) => flagActivo(item) && puedeVerNavItem(item.permission, canRead),
  );
  const visibleMobile = (mobileNavigation as readonly (NavItem & { primary?: boolean })[]).filter(flagActivo);
  const visiblePlatform = isPlatformAdmin ? platformNavigation : [];
  const currentLabel = routeLabel(pathname);

  // Con el menú abierto el fondo no debe scrollear: si no, al deslizar dentro
  // del menú se mueve la página de atrás y se pierde el lugar donde se estaba.
  useEffect(() => {
    if (!menuOpen) return;
    const previous = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = previous;
    };
  }, [menuOpen]);

  // Cerrar con Escape, y cerrar solo al navegar a otra ruta.
  useEffect(() => {
    setMenuOpen(false);
  }, [pathname]);

  useEffect(() => {
    if (!menuOpen) return;
    const onKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") setMenuOpen(false);
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [menuOpen]);

  const submitQuickSearch = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const term = quickSearch.trim();
    if (!term) return;
    router.push(`/dashboard/ots?search=${encodeURIComponent(term)}`);
    setQuickSearch("");
  };

  const sidebarContent = (onNavigate?: () => void) => (
    <>
      <Link
        href="/dashboard/ots/nueva"
        onClick={onNavigate}
        className="flex min-h-[48px] items-center justify-center gap-2 rounded-lg bg-primary px-4 text-base font-semibold text-primary-foreground shadow-sm transition-colors duration-150 hover:bg-primary/90"
      >
        <Plus className="h-5 w-5" />
        Nueva recepción
      </Link>

      <div className="mt-4">
        <GlobalSyncStatus compact />
      </div>

      <div className="mt-2 min-h-0 flex-1 overflow-y-auto py-4">
        <NavGroup title="Operación" items={visibleMain} pathname={pathname} onNavigate={onNavigate} />
        <NavGroup
          title="Administración"
          items={visibleSecondary}
          pathname={pathname}
          onNavigate={onNavigate}
        />
        <NavGroup
          title="Plataforma"
          items={visiblePlatform}
          pathname={pathname}
          onNavigate={onNavigate}
        />
      </div>
    </>
  );

  return (
    <div className="min-h-screen bg-background">
      {/*
       * Barra lateral fija en computadora. 280px en vez de 320px: a 1024px de
       * ancho eso le devuelve 40px de aire al contenido, que es justo donde el
       * layout se sentía apretado.
       */}
      <aside className="fixed inset-y-0 left-0 z-40 hidden w-[280px] flex-col border-r border-border bg-surface px-3 py-4 lg:flex">
        <Link href="/dashboard" className="flex items-center gap-2.5 rounded-lg px-3 py-1">
          <img src="/logo-mark.png" alt="" aria-hidden="true" className="h-8 w-8 object-contain" />
          <span className="text-base font-semibold tracking-tight text-foreground">MBtaller</span>
        </Link>

        <div className="mt-5 flex min-h-0 flex-1 flex-col">{sidebarContent()}</div>

        <UserCard />
      </aside>

      <div className="lg:pl-[280px]">
        {/*
         * Encabezado pegajoso. Se quitó la tarjeta de usuario duplicada que
         * repetía lo que ya dice la barra lateral.
         */}
        <header className="sticky top-0 z-30 border-b border-border bg-surface/80 backdrop-blur-xl">
          <div className="mx-auto flex h-16 w-full max-w-[1400px] items-center gap-3 px-4 md:px-6 xl:px-8">
            <Button
              variant="ghost"
              size="icon"
              className="-ml-2 shrink-0 lg:hidden"
              onClick={() => setMenuOpen(true)}
              aria-label="Abrir menú"
            >
              <Menu className="h-6 w-6" />
            </Button>

            <h1 className="min-w-0 flex-1 truncate text-lg font-semibold tracking-tight text-foreground lg:text-xl">
              {currentLabel}
            </h1>

            <form onSubmit={submitQuickSearch} className="hidden w-full max-w-xs md:block">
              <div className="relative">
                <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-subtle-foreground" />
                <Input
                  value={quickSearch}
                  onChange={(event) => setQuickSearch(event.target.value)}
                  placeholder="Buscar placa o cliente"
                  aria-label="Buscar placa o cliente"
                  className="h-10 bg-muted pl-9"
                />
              </div>
            </form>

            <div className="flex shrink-0 items-center gap-2">
              <TenantSwitcher />
              <div className="lg:hidden">
                <GlobalSyncStatus compact />
              </div>
            </div>
          </div>
        </header>

        {/*
         * `pb-bottom-nav` deja libre el alto real de la barra inferior, incluida
         * el área segura de iOS. Antes era un espaciador fijo de 64px contra una
         * barra de ~68px, y la última fila de cada lista quedaba tapada.
         */}
        <main className="mx-auto w-full max-w-[1400px] px-4 py-5 pb-bottom-nav md:px-6 md:py-6 lg:pb-10 xl:px-8">
          {children}
        </main>
      </div>

      {/* Menú lateral en celular y tablet */}
      {menuOpen ? (
        <div className="fixed inset-0 z-50 lg:hidden">
          <div
            className="absolute inset-0 animate-fade-in bg-foreground/25 backdrop-blur-[2px]"
            onClick={() => setMenuOpen(false)}
          />
          <div
            role="dialog"
            aria-modal="true"
            aria-label="Menú de navegación"
            className="absolute inset-y-0 left-0 flex w-[86vw] max-w-[320px] flex-col border-r border-border bg-surface px-3 py-4 shadow-2xl"
          >
            <div className="flex items-center justify-between px-3">
              <div className="flex items-center gap-2.5">
                <img src="/logo-mark.png" alt="" aria-hidden="true" className="h-8 w-8 object-contain" />
                <span className="text-base font-semibold tracking-tight text-foreground">
                  MBtaller
                </span>
              </div>
              <Button
                variant="ghost"
                size="icon"
                onClick={() => setMenuOpen(false)}
                aria-label="Cerrar menú"
              >
                <X className="h-5 w-5" />
              </Button>
            </div>

            <div className="mt-5 flex min-h-0 flex-1 flex-col">
              {sidebarContent(() => setMenuOpen(false))}
            </div>

            <UserCard />
          </div>
        </div>
      ) : null}

      {/*
       * Barra inferior en celular y tablet. "Nueva" va al centro y destacada:
       * es la acción que más se repite en el día y tiene que encontrarse sin
       * buscarla.
       */}
      <nav
        aria-label="Navegación principal"
        className="safe-bottom fixed inset-x-0 bottom-0 z-40 border-t border-border bg-surface/95 backdrop-blur-xl lg:hidden"
      >
        <div
          className="mx-auto grid max-w-lg"
          style={{ gridTemplateColumns: `repeat(${visibleMobile.length}, minmax(0, 1fr))` }}
        >
          {visibleMobile.map((item) => {
            const active = isRouteActive(pathname, item.href);
            const primary = Boolean(item.primary);

            return (
              <Link
                key={item.href}
                href={item.href}
                aria-current={active ? "page" : undefined}
                className={cn(
                  "flex min-h-[56px] flex-col items-center justify-center gap-1 px-1 py-2 transition-[color,transform] duration-150 active:scale-[0.97]",
                  active ? "text-primary" : "text-muted-foreground",
                )}
              >
                <span
                  className={cn(
                    "flex h-7 w-7 items-center justify-center rounded-full transition-colors",
                    primary && "bg-primary text-primary-foreground",
                  )}
                >
                  <item.icon className="h-5 w-5" />
                </span>
                <span className="w-full truncate text-center text-[11px] font-medium leading-none">
                  {item.label}
                </span>
              </Link>
            );
          })}
        </div>
      </nav>
    </div>
  );
}
