"use client";

import { useEffect, useState } from "react";

import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { CalendarRange, ChevronDown, LaptopMinimalCheck, LogOut, Menu, Package, RotateCcw, SlidersHorizontal, Users } from "lucide-react";
import type { UserRole } from "@rental/shared";

import { Button } from "../ui/button";
import { cn } from "../../lib/cn";
import { ChatLauncher } from "./chat-launcher";
import { useRuntimeUiConfig } from "./runtime-ui-config-provider";
import { useSessionContext } from "./session-provider";
import { desktopViewLimits, mobileViewLimits, useViewSettings } from "./view-settings-provider";
import { useIsMobile } from "../../lib/use-is-mobile";

type NavigationItem = {
  href: string;
  label: string;
  icon: typeof CalendarRange;
  roles?: UserRole[];
};

const navigation: NavigationItem[] = [
  { href: "/dashboard", label: "Timeline", icon: CalendarRange, roles: ["admin", "operator", "viewer"] },
  { href: "/equipment", label: "Sprzęt", icon: LaptopMinimalCheck, roles: ["admin", "operator", "viewer"] },
  { href: "/operations", label: "Operacje", icon: Package, roles: ["admin", "operator", "viewer", "technik"] },
  { href: "/stats", label: "Statystyki", icon: SlidersHorizontal, roles: ["admin"] },
  { href: "/users", label: "Użytkownicy", icon: Users, roles: ["admin"] }
];

const shellContainerStyle = {
  maxWidth: "min(calc((100vw + 1800px) / 2), calc(100vw - 1.5rem))"
} satisfies React.CSSProperties;

const topNavActiveClassName = "border-[#ff5a1f] bg-[#ff5a1f] text-white";

const isEditableTarget = (target: EventTarget | null) => {
  if (!(target instanceof HTMLElement)) {
    return false;
  }

  const tagName = target.tagName.toLowerCase();

  return (
    target.isContentEditable ||
    tagName === "input" ||
    tagName === "textarea" ||
    tagName === "select" ||
    Boolean(target.closest("[contenteditable='true'], input, textarea, select"))
  );
};

const hasOpenModal = () => {
  if (typeof document === "undefined") {
    return false;
  }

  return Boolean(document.querySelector("[data-rental-modal='true']"));
};

export const AppShell = ({ children }: { children: React.ReactNode }) => {
  const pathname = usePathname();
  const router = useRouter();
  const { session, setSession } = useSessionContext();
  const { timelineCopy } = useRuntimeUiConfig();
  const { allSettings, resetSettingsForMode, updateSettingsForMode } = useViewSettings();
  const isMobile = useIsMobile();
  const [menuOpen, setMenuOpen] = useState(false);
  const [viewMenuOpen, setViewMenuOpen] = useState(false);

  const currentRole = session?.user.role;
  const canAccessLink = (item: NavigationItem) => !item.roles || (currentRole ? item.roles.includes(currentRole) : false);
  const isAdminOnlyLink = (item: NavigationItem) => Boolean(item.roles && item.roles.length === 1 && item.roles[0] === "admin");
  const primaryLinks = navigation.filter((item) => canAccessLink(item) && !isAdminOnlyLink(item));
  const adminMenuLinks = navigation.filter((item) => isAdminOnlyLink(item));
  const hasAdminMenu = session?.user.role === "admin" && adminMenuLinks.length > 0;
  const homeHref = currentRole === "technik" ? "/operations" : "/dashboard";
  const headerTitle = pathname.startsWith("/dashboard") ? timelineCopy.title : "";

  useEffect(() => {
    setMenuOpen(false);
  }, [pathname]);

  useEffect(() => {
    if (!menuOpen) {
      setViewMenuOpen(false);
    }
  }, [menuOpen]);

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
        return;
      }

      if (hasOpenModal()) {
        return;
      }

      if (isEditableTarget(event.target)) {
        return;
      }

      if (event.key === "1") {
        if (!navigation.some((item) => item.href === "/dashboard" && canAccessLink(item))) {
          return;
        }

        event.preventDefault();
        router.push("/dashboard");
        return;
      }

      if (event.key === "2") {
        if (!navigation.some((item) => item.href === "/equipment" && canAccessLink(item))) {
          return;
        }

        event.preventDefault();
        router.push("/equipment");
        return;
      }

      if (event.key === "3") {
        if (!navigation.some((item) => item.href === "/operations" && canAccessLink(item))) {
          return;
        }

        event.preventDefault();
        router.push("/operations");
        return;
      }

      if (event.key === "4" && session?.user.role === "admin" && navigation.some((item) => item.href === "/users" && canAccessLink(item))) {
        event.preventDefault();
        router.push("/users");
      }
    };

    window.addEventListener("keydown", handleKeyDown);

    return () => {
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [currentRole, router, session?.user.role]);

  const logout = () => {
    setSession(null);
    router.replace("/login");
  };

  const menuPanel = (
    <section className={cn("rounded-[26px] border border-line bg-white/90", isMobile ? "p-3" : "p-4")}>
      <div className="text-sm font-semibold text-ink">
        {hasAdminMenu ? (isMobile ? "ADMIN" : "Administracja") : "Menu"}
      </div>

      <nav className={cn("grid", isMobile ? "mt-2 gap-1.5" : "mt-3 gap-2")}>
        {adminMenuLinks.map((item) => {
          const Icon = item.icon;
          const active = pathname.startsWith(item.href);

          return (
            <Link
              key={item.href}
              href={item.href}
              className={cn(
                "flex items-center rounded-2xl border text-sm font-semibold transition",
                isMobile ? "gap-2 px-3 py-2.5" : "gap-3 px-4 py-3",
                active
                  ? "border-accent bg-accent text-white shadow-soft"
                  : "border-line bg-white/80 text-ink hover:border-accent/50 hover:bg-white"
              )}
            >
              <Icon className="h-4 w-4" />
              {item.label}
            </Link>
          );
        })}

        <button
          className={cn(
            "flex items-center rounded-2xl border text-sm font-semibold transition",
            isMobile ? "gap-2 px-3 py-2.5" : "gap-3 px-4 py-3",
            viewMenuOpen
              ? "border-accent bg-[#f8f3ea] text-ink"
              : "border-line bg-white/80 text-ink hover:border-accent/50 hover:bg-white"
          )}
          type="button"
          onClick={() => setViewMenuOpen((open) => !open)}
        >
          <CalendarRange className="h-4 w-4" />
          <span>Timeline</span>
          <ChevronDown className={cn("ml-auto h-4 w-4 text-muted transition-transform", viewMenuOpen && "rotate-180")} />
        </button>
      </nav>

      {viewMenuOpen ? (
        <>
          <div className={cn("grid", isMobile ? "mt-3 gap-3" : "mt-4 gap-4")}>
            {([
              { mode: "desktop", label: "Desktop", limits: desktopViewLimits },
              { mode: "mobile", label: "Mobile", limits: mobileViewLimits }
            ] as const).map((config) => (
              <div key={config.mode} className="rounded-2xl border border-line bg-[rgba(248,245,236,0.72)] p-3">
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <div className="text-sm font-semibold text-ink">{config.label}</div>
                  <Button
                    className="h-8 px-3 text-xs uppercase tracking-[0.12em]"
                    variant="ghost"
                    onClick={() => resetSettingsForMode(config.mode)}
                  >
                    <RotateCcw className="h-3.5 w-3.5" />
                    Reset
                  </Button>
                </div>

                <div className={cn("grid lg:grid-cols-3", isMobile ? "mt-3 gap-3" : "mt-4 gap-4")}>
                  <label className="block space-y-2">
                    <span className="flex items-center justify-between text-[11px] font-semibold uppercase tracking-[0.16em] text-muted">
                      <span>Komórka</span>
                      <span>{allSettings[config.mode].dayWidth}px</span>
                    </span>
                    <input
                      className="w-full accent-[#b66b27]"
                      max={config.limits.dayWidth.max}
                      min={config.limits.dayWidth.min}
                      step={2}
                      type="range"
                      value={allSettings[config.mode].dayWidth}
                      onChange={(event) => updateSettingsForMode(config.mode, { dayWidth: Number(event.target.value) })}
                    />
                  </label>

                  <label className="block space-y-2">
                    <span className="flex items-center justify-between text-[11px] font-semibold uppercase tracking-[0.16em] text-muted">
                      <span>Wiersz</span>
                      <span>{allSettings[config.mode].rowHeight}px</span>
                    </span>
                    <input
                      className="w-full accent-[#b66b27]"
                      max={config.limits.rowHeight.max}
                      min={config.limits.rowHeight.min}
                      step={2}
                      type="range"
                      value={allSettings[config.mode].rowHeight}
                      onChange={(event) => updateSettingsForMode(config.mode, { rowHeight: Number(event.target.value) })}
                    />
                  </label>

                  <label className="block space-y-2">
                    <span className="flex items-center justify-between text-[11px] font-semibold uppercase tracking-[0.16em] text-muted">
                      <span>Urządzenia</span>
                      <span>{allSettings[config.mode].labelWidth}px</span>
                    </span>
                    <input
                      className="w-full accent-[#b66b27]"
                      max={config.limits.labelWidth.max}
                      min={config.limits.labelWidth.min}
                      step={4}
                      type="range"
                      value={allSettings[config.mode].labelWidth}
                      onChange={(event) => updateSettingsForMode(config.mode, { labelWidth: Number(event.target.value) })}
                    />
                  </label>
                </div>
              </div>
            ))}
          </div>

          <p className={cn("text-xs text-muted", isMobile ? "mt-2" : "mt-3")}>
            Ustawienia widoku są zapisywane osobno dla desktopu i telefonu dla zalogowanego użytkownika w tej przeglądarce.
          </p>
        </>
      ) : null}
    </section>
  );

  return (
    <div className="min-h-screen">
      <div className="flex min-h-screen flex-col">
        <header className="z-40 border-b border-line/80 bg-[rgba(250,247,239,0.92)] backdrop-blur">
          <div className="relative mx-auto flex w-full flex-col gap-3 px-4 py-3 lg:px-8" style={shellContainerStyle}>
            {headerTitle ? (
              <h1 className="pointer-events-none absolute left-1/2 top-1/2 z-10 max-w-[34vw] -translate-x-1/2 -translate-y-1/2 truncate text-center text-base font-semibold leading-none text-ink sm:text-xl lg:text-2xl">
                {headerTitle}
              </h1>
            ) : null}
            <div className="flex items-center justify-between gap-4">
              <div className="flex min-w-0 flex-1 flex-col gap-3 sm:flex-row sm:items-center">
                <div className="flex min-w-0 items-center gap-2">
                  {isMobile ? (
                    <Button
                      aria-expanded={menuOpen}
                      aria-label={menuOpen ? "Zwiń menu" : "Rozwiń menu"}
                      className="h-9 w-9 shrink-0 rounded-lg p-0"
                      variant="secondary"
                      onClick={() => setMenuOpen((open) => !open)}
                    >
                      <span className="flex flex-col items-center justify-center gap-[3px]">
                        <span className="block h-[2px] w-4 rounded-full bg-current" />
                        <span className="block h-[2px] w-4 rounded-full bg-current" />
                        <span className="block h-[2px] w-4 rounded-full bg-current" />
                      </span>
                    </Button>
                  ) : null}
                  <Link
                    href={homeHref}
                    className="flex max-w-full items-center px-2 py-1.5"
                    aria-label="Notebooking"
                  >
                    <img
                      src="/branding/notebooking.png"
                      alt="Notebooking"
                      className={cn("w-auto max-w-full", isMobile ? "h-8" : "h-10 sm:h-12 lg:h-14")}
                      draggable={false}
                    />
                  </Link>
                </div>

                {!isMobile ? (
                  <div className="flex min-w-0 items-center gap-2 overflow-x-auto">
                    {primaryLinks.map((item) => {
                      const Icon = item.icon;
                      const active = pathname.startsWith(item.href);

                      return (
                        <Link
                          key={item.href}
                          href={item.href}
                          className={cn(
                            "inline-flex h-8 items-center gap-1.5 rounded-lg border px-2.5 text-[11px] font-semibold uppercase tracking-[0.12em] transition",
                            active
                              ? topNavActiveClassName
                              : "border-line bg-white/86 text-ink hover:border-accent/50 hover:bg-white"
                          )}
                        >
                          <Icon className="h-3.5 w-3.5" />
                          <span>{item.label}</span>
                        </Link>
                      );
                    })}
                  </div>
                ) : null}
              </div>

              {!isMobile ? (
                <div className="relative flex shrink-0 items-center gap-2 self-center lg:gap-3">
                  <div className="hidden self-center text-right lg:block">
                    <p className="text-sm font-semibold text-ink">{session?.user.name}</p>
                    <p className="text-xs uppercase tracking-[0.18em] text-muted">{session?.user.role}</p>
                  </div>
                  <Button
                    aria-expanded={menuOpen}
                    aria-label={menuOpen ? "Zwiń menu" : "Rozwiń menu"}
                    className="h-8 shrink-0 rounded-lg px-2.5 text-[11px] uppercase tracking-[0.12em]"
                    variant="secondary"
                    onClick={() => setMenuOpen((open) => !open)}
                  >
                    <Menu className="h-3.5 w-3.5" />
                    <span>Menu</span>
                    <ChevronDown className={cn("h-3.5 w-3.5 transition-transform", menuOpen && "rotate-180")} />
                  </Button>
                  <Button className="px-2.5 sm:px-3.5" variant="ghost" onClick={logout}>
                    <LogOut className="h-4 w-4" />
                    <span className="hidden sm:inline">Wyloguj</span>
                  </Button>

                  <div
                    className={cn(
                      "pointer-events-none absolute right-0 top-full z-50 mt-2 w-[min(420px,calc(100vw-2rem))] origin-top-right transition duration-200",
                      menuOpen ? "translate-y-0 scale-100 opacity-100" : "-translate-y-2 scale-[0.98] opacity-0"
                    )}
                  >
                    <div className="rounded-[28px] border border-line bg-white/95 p-3 shadow-soft backdrop-blur lg:p-4">
                      <div className={cn("grid gap-3", menuOpen && "pointer-events-auto")}>{menuPanel}</div>
                    </div>
                  </div>
                </div>
              ) : null}
            </div>
          </div>
        </header>

        {isMobile && menuOpen ? (
          <div className="border-b border-line/80 bg-[rgba(250,247,239,0.88)]">
            <div className="mx-auto w-full px-4 pb-3" style={shellContainerStyle}>
              <div className="w-[250px] max-w-[calc(100vw-2rem)] space-y-3 rounded-[22px] border border-line bg-white/92 p-3 shadow-soft">
                {menuPanel}

                <Button
                  className="w-full"
                  variant="ghost"
                  onClick={() => {
                    setMenuOpen(false);
                    logout();
                  }}
                >
                  <LogOut className="h-4 w-4" />
                  Wyloguj
                </Button>
              </div>
            </div>
          </div>
        ) : null}

        <main className="mx-auto flex w-full flex-1 flex-col px-4 pt-4 pb-16 lg:px-8 lg:pt-8 lg:pb-[2px]" style={shellContainerStyle}>
          {children}
        </main>
      </div>

      {isMobile ? (
        <>
          <nav className="fixed inset-x-0 bottom-0 z-50 border-t border-line/80 bg-[rgba(250,247,239,0.96)] px-3 pb-[calc(env(safe-area-inset-bottom,0px)+0.5rem)] pt-2 backdrop-blur">
            <div
              className="mx-auto grid w-full max-w-[560px] gap-2"
              style={{ gridTemplateColumns: `repeat(${Math.max(primaryLinks.length, 1)}, minmax(0, 1fr))` }}
            >
              {primaryLinks.map((item) => (
                <Link
                  key={item.href}
                  href={item.href}
                  className={cn(
                    "flex h-7 items-center justify-center rounded-lg border px-3 text-[11px] font-semibold uppercase tracking-[0.12em] transition",
                    pathname.startsWith(item.href)
                      ? topNavActiveClassName
                      : "border-line bg-white/92 text-ink"
                  )}
                >
                  <span>{item.label}</span>
                </Link>
              ))}
            </div>
          </nav>
        </>
      ) : null}

      <ChatLauncher />
    </div>
  );
};
