"use client";

import { useEffect, useState } from "react";

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

import { Button } from "../ui/button";
import { cn } from "../../lib/cn";
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?: string[];
};

const navigation: NavigationItem[] = [
  { href: "/dashboard", label: "Timeline", icon: CalendarRange },
  { href: "/equipment", label: "Sprzęt", icon: LaptopMinimalCheck },
  { 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 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"))
  );
};

export const AppShell = ({ children }: { children: React.ReactNode }) => {
  const pathname = usePathname();
  const router = useRouter();
  const { session, setSession } = useSessionContext();
  const { settings: viewSettings, updateSettings, resetSettings } = useViewSettings();
  const isMobile = useIsMobile();
  const [menuOpen, setMenuOpen] = useState(false);
  const viewLimits = isMobile ? mobileViewLimits : desktopViewLimits;

  const primaryLinks = navigation.filter((item) => item.href !== "/users");
  const adminMenuLinks = navigation.filter((item) => item.roles?.includes("admin"));
  const hasAdminMenu = session?.user.role === "admin" && adminMenuLinks.length > 0;

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

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

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

      if (event.key === "1") {
        event.preventDefault();
        router.push("/dashboard");
        return;
      }

      if (event.key === "2") {
        event.preventDefault();
        router.push("/equipment");
        return;
      }

      if (event.key === "3" && session?.user.role === "admin") {
        event.preventDefault();
        router.push("/users");
      }
    };

    window.addEventListener("keydown", handleKeyDown);

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

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

  return (
    <div className="min-h-screen">
      <div className="flex min-h-screen flex-col">
        <header className="sticky top-0 z-40 border-b border-line/80 bg-[rgba(250,247,239,0.92)] backdrop-blur">
          <div className="mx-auto flex w-full flex-col gap-3 px-4 py-3 lg:px-8" style={shellContainerStyle}>
            <div className="flex items-start 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-3">
                  <div className="rounded-2xl bg-accent px-3 py-2 text-sm font-semibold text-white">RS</div>
                  <div className="min-w-0">
                    <p className="truncate text-xs uppercase tracking-[0.22em] text-muted">Rental operations</p>
                    <h1 className="truncate text-base font-semibold text-ink lg:text-xl">
                      Planowanie i administracja wynajmu
                    </h1>
                  </div>
                </div>

                <div className="flex min-w-0 items-center gap-2 overflow-x-auto pb-1 sm:pb-0">
                  {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
                            ? "border-accent bg-accent text-white"
                            : "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>
              </div>

              <div className="flex shrink-0 items-center gap-2 lg:gap-3">
                <div className="hidden 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>
            </div>

            <div
              className={cn(
                "overflow-hidden transition-[max-height,opacity] duration-300",
                menuOpen ? "max-h-[560px] opacity-100" : "max-h-0 opacity-0"
              )}
            >
              <div className="rounded-[28px] border border-line bg-white/88 p-3 shadow-soft lg:p-4">
                <div className={cn("grid gap-3", hasAdminMenu && "xl:grid-cols-[minmax(0,1.3fr)_minmax(280px,0.7fr)]")}>
                  <section className="rounded-[26px] border border-line bg-[rgba(248,245,236,0.9)] p-4">
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <div className="flex items-center gap-2 text-sm font-semibold text-ink">
                        <SlidersHorizontal className="h-4 w-4 text-accent" />
                        Widok
                      </div>
                      <Button className="h-8 px-3 text-xs uppercase tracking-[0.12em]" variant="ghost" onClick={resetSettings}>
                        <RotateCcw className="h-3.5 w-3.5" />
                        Reset
                      </Button>
                    </div>

                    <div className="mt-4 grid gap-4 lg:grid-cols-3">
                      <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>{viewSettings.dayWidth}px</span>
                        </span>
                        <input
                          className="w-full accent-[#b66b27]"
                          max={viewLimits.dayWidth.max}
                          min={viewLimits.dayWidth.min}
                          step={2}
                          type="range"
                          value={viewSettings.dayWidth}
                          onChange={(event) => updateSettings({ 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>{viewSettings.rowHeight}px</span>
                        </span>
                        <input
                          className="w-full accent-[#b66b27]"
                          max={viewLimits.rowHeight.max}
                          min={viewLimits.rowHeight.min}
                          step={2}
                          type="range"
                          value={viewSettings.rowHeight}
                          onChange={(event) => updateSettings({ 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>Pasek</span>
                          <span>{viewSettings.bookingBarHeight}px</span>
                        </span>
                        <input
                          className="w-full accent-[#b66b27]"
                          max={Math.min(viewLimits.bookingBarHeight.max, Math.max(viewSettings.rowHeight - 2, viewLimits.bookingBarHeight.min))}
                          min={viewLimits.bookingBarHeight.min}
                          step={2}
                          type="range"
                          value={viewSettings.bookingBarHeight}
                          onChange={(event) => updateSettings({ bookingBarHeight: Number(event.target.value) })}
                        />
                      </label>
                    </div>

                    <p className="mt-3 text-xs text-muted">
                      Ustawienia widoku są zapisywane osobno dla zalogowanego użytkownika w tej przeglądarce.
                    </p>
                  </section>

                  {hasAdminMenu ? (
                    <section className="rounded-[26px] border border-line bg-white/90 p-4">
                      <div className="text-sm font-semibold text-ink">Administracja</div>
                      <nav className="mt-3 grid 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 gap-3 rounded-2xl border px-4 py-3 text-sm font-semibold transition",
                                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>
                          );
                        })}
                      </nav>
                    </section>
                  ) : null}
                </div>
              </div>
            </div>
          </div>
        </header>

        <main className="mx-auto flex w-full flex-1 flex-col px-4 py-4 pb-8 lg:px-8 lg:py-8" style={shellContainerStyle}>
          {children}
        </main>
      </div>
    </div>
  );
};
