"use client";

import { useEffect, useState } from "react";
import { usePathname, useRouter } from "next/navigation";
import {
  ArrowUp,
  BedDouble,
  CalendarCheck,
  ChevronLeft,
  ChevronRight,
  Facebook,
  House,
  Instagram,
  Mail,
  MapPin,
  Menu,
  Phone,
  ShieldCheck,
  Sparkles,
  X,
} from "lucide-react";
import { hotel } from "./data";

type PopupSettings = {
  enabled: boolean;
  images?: PopupImage[];
  imageUrl: string;
  altText: string;
  linkUrl: string;
};

type PopupImage = {
  imageUrl: string;
  altText: string;
  linkUrl: string;
};

function TikTokIcon({ size = 18 }: { size?: number }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" aria-hidden="true" focusable="false">
      <path
        fill="currentColor"
        d="M16.6 3c.4 3 2 4.8 4.7 5v3.4a8.6 8.6 0 0 1-4.6-1.4v5.6c0 4-2.7 6.4-6.2 6.4A6.1 6.1 0 0 1 4.3 16c0-3.7 3-6.4 6.8-6.1v3.5c-1.8-.3-3.2.8-3.2 2.5 0 1.5 1.1 2.5 2.5 2.5 1.6 0 2.7-.9 2.7-3V3h3.5Z"
      />
    </svg>
  );
}

function getPopupImages(settings: PopupSettings | null) {
  if (!settings) return [];
  if (settings.images?.length) return settings.images;
  if (!settings.imageUrl) return [];
  return [{ imageUrl: settings.imageUrl, altText: settings.altText, linkUrl: settings.linkUrl }];
}

export function Reveal() {
  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) entry.target.classList.add("is-visible");
        });
      },
      { threshold: 0.16 }
    );

    document.querySelectorAll(".reveal").forEach((el) => observer.observe(el));
    return () => observer.disconnect();
  }, []);

  return null;
}

const motionSelector = [
  ".section-title",
  ".experience-card",
  ".group-package-card",
  ".room-card",
  ".story-card",
  ".facility-card",
  ".gallery-card",
  ".gallery-film-card",
  ".menu-item",
  ".luxury-points span",
  ".metric-row span",
  ".intro-image",
  ".intro-copy",
  ".location-grid > *",
  ".room-detail-section",
  ".footer-grid > *",
].join(",");

// Site-wide scroll animation: cards and headings below the fold fade up as they
// scroll into view, with a short stagger between siblings. Content that is already
// on screen is left alone so nothing flickers on load. Anything still hidden when
// the effect stops (navigation, React re-mount) is revealed, so content can never
// get stuck invisible.
export function MotionEffects() {
  useEffect(() => {
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;

    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (!entry.isIntersecting) return;
          entry.target.classList.add("motion-in");
          observer.unobserve(entry.target);
        });
      },
      { threshold: 0.12, rootMargin: "0px 0px -40px 0px" }
    );

    const seen = new WeakSet<Element>();
    const tag = () => {
      document.querySelectorAll<HTMLElement>(motionSelector).forEach((element) => {
        if (seen.has(element)) return;
        seen.add(element);
        if (
          element.classList.contains("motion-item") ||
          element.classList.contains("reveal") ||
          element.closest(".admin-shell") ||
          element.getBoundingClientRect().top < window.innerHeight
        ) {
          return;
        }
        const siblings = element.parentElement
          ? Array.from(element.parentElement.children).filter((child) => child.matches(motionSelector))
          : [];
        element.style.setProperty("--motion-delay", `${Math.min(siblings.indexOf(element), 5) * 70}ms`);
        element.classList.add("motion-item");
        observer.observe(element);
      });
    };

    tag();
    let frame = 0;
    const mutations = new MutationObserver(() => {
      if (frame) return;
      frame = requestAnimationFrame(() => {
        frame = 0;
        tag();
      });
    });
    mutations.observe(document.body, { childList: true, subtree: true });
    return () => {
      cancelAnimationFrame(frame);
      mutations.disconnect();
      observer.disconnect();
      document.querySelectorAll(".motion-item:not(.motion-in)").forEach((element) => element.classList.add("motion-in"));
    };
  }, []);

  return null;
}

export function Logo() {
  return (
    <a className="logo" href="/" aria-label={`${hotel.name} home`}>
      <span className="logo-mark">
        <img src="/images/logo.png" alt="" aria-hidden="true" />
      </span>
    </a>
  );
}

export function SiteNav() {
  const pathname = usePathname();
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 28);
    onScroll();
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  const links = [
    ["Home", "/"],
    ["Rooms", "/rooms"],
    ["Menu", "/menu"],
    ["Gallery", "/gallery"],
  ];

  return (
    <nav className={`site-nav ${scrolled ? "is-scrolled" : ""} ${/^\/rooms\/[^/]+/.test(pathname) ? "is-solid" : ""}`}>
      <div className="container">
        <div className="nav-main">
          <Logo />
          <div className="nav-menu-panel">
            <div className="nav-links">
              {links.map(([label, href]) => (
                <a key={label} href={href} className={pathname === href || (href !== "/" && pathname.startsWith(`${href}/`)) ? "active" : ""} aria-current={pathname === href ? "page" : undefined}>
                  <span>{label}</span>
                  <span>{label}</span>
                </a>
              ))}
            </div>
            <a className="nav-action" href="/booking">
              Book Now
            </a>
          </div>
          <button
            className="icon-button menu-button"
            aria-label="Toggle menu"
            aria-expanded={menuOpen}
            onClick={() => setMenuOpen((value) => !value)}
          >
            {menuOpen ? <X /> : <Menu />}
          </button>
        </div>
      </div>
      <div className={`mobile-menu ${menuOpen ? "open" : ""}`}>
        {links.map(([label, href]) => (
          <a key={label} href={href} className={pathname === href || (href !== "/" && pathname.startsWith(`${href}/`)) ? "active" : ""} aria-current={pathname === href ? "page" : undefined} onClick={() => setMenuOpen(false)}>
            {label}
          </a>
        ))}
        <a className="mobile-book-action" href="/booking" onClick={() => setMenuOpen(false)}>
          Book Now
        </a>
      </div>
    </nav>
  );
}

export function SiteFooter() {
  return (
    <footer className="footer">
      <div className="container footer-grid">
        <div className="footer-brand">
          <Logo />
          <p>{hotel.tagline}</p>
          <div className="footer-pills">
            <span>
              <ShieldCheck size={15} /> Secure booking
            </span>
            <span>
              <Sparkles size={15} /> Managed stay
            </span>
          </div>
        </div>
        <div>
          <h4>Hotel</h4>
          <a href="/rooms">Rooms</a>
          <a href="/menu">Menu</a>
          <a href="/gallery">Gallery</a>
          <a href="/booking">Booking</a>
        </div>
        <div>
          <h4>Services</h4>
          <a href="/rooms">Comfortable rooms</a>
          <a href="/menu">Terrace menu</a>
          <a href="/booking">Guest reservations</a>
          <a href="/gallery">Garden spaces</a>
          <a href="/booking">Room booking</a>
        </div>
        <div>
          <h4>Contact</h4>
          <p className="footer-line">
            <MapPin size={15} /> {hotel.area}
          </p>
          <a className="footer-line" href={`tel:${hotel.phone}`}>
            <Phone size={15} /> {hotel.phone}
          </a>
          <a className="footer-line" href={`mailto:${hotel.email}`}>
            <Mail size={15} /> {hotel.email}
          </a>
          <div className="footer-social-links" aria-label="Social links">
            <a
              href="https://www.instagram.com/bass_restro.official/"
              target="_blank"
              rel="noreferrer"
              aria-label="Bass Restaurant on Instagram"
              title="Instagram"
            >
              <Instagram size={18} />
            </a>
            <a
              href="https://www.facebook.com/bassrestaurant.official"
              target="_blank"
              rel="noreferrer"
              aria-label="Bass Restaurant on Facebook"
              title="Facebook"
            >
              <Facebook size={18} />
            </a>
            <a
              href="https://www.tiktok.com/@bass.resort"
              target="_blank"
              rel="noreferrer"
              aria-label="Bass Resort on TikTok"
              title="TikTok"
            >
              <TikTokIcon size={18} />
            </a>
          </div>
        </div>
      </div>
      <div className="container copyright">
        <p>Copyright 2026 {hotel.name}. All rights reserved.</p>
        <div className="footer-quick-links">
          <a href="/booking">
            <CalendarCheck size={14} /> Reservations
          </a>
          <a href="/rooms">
            <BedDouble size={14} /> Rooms
          </a>
        </div>
        <a
          className="vividify-credit"
          href="https://vividifysolutions.com/"
          target="_blank"
          rel="noreferrer"
          aria-label="Designed and developed by Vividify Solutions"
        >
          <span>Designed &amp; developed by</span>
          <img src="/images/vividify-white.png" alt="Vividify Solutions" />
        </a>
      </div>
    </footer>
  );
}

export function PromoPopup() {
  const [settings, setSettings] = useState<PopupSettings | null>(null);
  const [visible, setVisible] = useState(false);
  const [activeImage, setActiveImage] = useState(0);

  useEffect(() => {
    let active = true;
    fetch("/api/settings/popup")
      .then((response) => (response.ok ? response.json() : null))
      .then((data: PopupSettings | null) => {
        if (!active || !data?.enabled || !getPopupImages(data).length) return;
        setSettings(data);
        setActiveImage(0);
        setVisible(true);
      })
      .catch(() => {
        // The website should stay quiet if popup settings cannot be loaded.
      });
    return () => {
      active = false;
    };
  }, []);

  function closePopup() {
    const images = getPopupImages(settings);
    if (activeImage < images.length - 1) {
      setActiveImage((index) => index + 1);
      return;
    }
    setVisible(false);
  }

  if (!settings || !visible) return null;

  const images = getPopupImages(settings);
  const current = images[activeImage] ?? images[0];
  if (!current) return null;

  function goToImage(index: number) {
    setActiveImage((index + images.length) % images.length);
  }

  const image = (
    <img src={current.imageUrl} alt={current.altText || "Bass Resort promotion"} />
  );

  return (
    <div className="promo-popup-backdrop" role="presentation" onClick={closePopup}>
      <section
        className="promo-popup-panel"
        role="dialog"
        aria-modal="true"
        aria-label="Bass Resort promotion"
        onClick={(event) => event.stopPropagation()}
      >
        <button type="button" className="promo-popup-close" onClick={closePopup} aria-label="Close promotion">
          <X size={22} />
        </button>
        {current.linkUrl ? (
          <a className="promo-popup-image" href={current.linkUrl} onClick={closePopup}>
            {image}
          </a>
        ) : (
          <div className="promo-popup-image">{image}</div>
        )}
        {images.length > 1 ? (
          <div className="promo-popup-controls" aria-label="Popup image controls">
            <button type="button" onClick={() => goToImage(activeImage - 1)} aria-label="Previous popup image">
              <ChevronLeft size={18} />
            </button>
            <div>
              {images.map((item, index) => (
                <button
                  key={`${item.imageUrl}-${index}`}
                  type="button"
                  className={index === activeImage ? "active" : ""}
                  onClick={() => goToImage(index)}
                  aria-label={`Show popup image ${index + 1}`}
                />
              ))}
            </div>
            <button type="button" onClick={() => goToImage(activeImage + 1)} aria-label="Next popup image">
              <ChevronRight size={18} />
            </button>
          </div>
        ) : null}
      </section>
    </div>
  );
}

export function NavigationLoader() {
  const pathname = usePathname();
  const router = useRouter();
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const finishTimer = window.setTimeout(() => setLoading(false), 180);
    return () => window.clearTimeout(finishTimer);
  }, [pathname]);

  useEffect(() => {
    const onClick = (event: MouseEvent) => {
      if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
      const link = (event.target as HTMLElement).closest("a");
      if (!link || link.target === "_blank" || link.hasAttribute("download")) return;
      const href = link.getAttribute("href");
      if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("tel:")) return;

      const destination = new URL(link.href, window.location.href);
      if (destination.origin !== window.location.origin) return;
      const current = `${window.location.pathname}${window.location.search}${window.location.hash}`;
      const next = `${destination.pathname}${destination.search}${destination.hash}`;
      if (current === next) return;

      event.preventDefault();
      setLoading(true);
      router.push(next);
      window.setTimeout(() => setLoading(false), 2500);
    };
    const onBackOrForward = () => setLoading(true);
    document.addEventListener("click", onClick);
    window.addEventListener("popstate", onBackOrForward);
    return () => {
      document.removeEventListener("click", onClick);
      window.removeEventListener("popstate", onBackOrForward);
    };
  }, [router]);

  return loading ? (
    <div className="navigation-loader" role="status" aria-live="polite" aria-label="Loading page">
      <div className="navigation-progress"><span /></div>
      <div className="navigation-loader-mark">
        <img src="/favicon.png" alt="" aria-hidden="true" />
        <span>Loading</span>
        <i><b /><b /><b /></i>
      </div>
    </div>
  ) : null;
}

export function ScrollToTop() {
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const onScroll = () => setVisible(window.scrollY > 420);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  return (
    <button
      type="button"
      className={`scroll-to-top ${visible ? "is-visible" : ""}`}
      aria-label="Scroll to top"
      onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
    >
      <ArrowUp size={20} aria-hidden="true" />
    </button>
  );
}

export function SectionTitle({
  eyebrow,
  title,
  description,
}: {
  eyebrow?: string;
  title: string;
  description?: string;
}) {
  return (
    <div className="section-title reveal">
      {eyebrow ? <span className="eyebrow">{eyebrow}</span> : null}
      <h2>{title}</h2>
      {description ? <p>{description}</p> : null}
    </div>
  );
}

export function PageHero({
  eyebrow,
  title,
  copy,
  image,
  imagePosition = "center center",
}: {
  eyebrow?: string;
  title: string;
  copy: string;
  image: string;
  imagePosition?: string;
}) {
  return (
    <section className="page-hero">
      <img src={image} alt={title} style={{ objectPosition: imagePosition }} loading="eager" decoding="async" />
      <div className="hero-shade" />
      <div className="page-hero-content reveal">
        <nav className="hero-breadcrumb" aria-label="Breadcrumb">
          <a href="/">
            <House size={14} />
            Home
          </a>
          <ChevronRight size={14} aria-hidden="true" />
          <span>{title}</span>
        </nav>
        {eyebrow ? <span className="eyebrow">{eyebrow}</span> : null}
        <h1>{title}</h1>
        <p>{copy}</p>
      </div>
    </section>
  );
}
