"use client";

import { useCallback, useEffect, useRef, useState } from "react";

import Image from "next/image";

import { ArrowLeft, ArrowRight, X } from "@phosphor-icons/react";

import { BLUR } from "@/lib/blurData";
import type { Project } from "@/lib/projects";

import { useLenis } from "@/components/LenisProvider";

type ProjectModalProps = {
  project: Project | null;
  onClose: () => void;
};

export default function ProjectModal({ project, onClose }: ProjectModalProps) {
  const { lenis } = useLenis();
  const dialogRef = useRef<HTMLDivElement | null>(null);
  const closeRef = useRef<HTMLButtonElement | null>(null);
  const [imageIndex, setImageIndex] = useState(0);

  // Reset gallery position per project; lock scroll while open.
  useEffect(() => {
    if (project) {
      // eslint-disable-next-line react-hooks/set-state-in-effect -- resets per-opened project
      setImageIndex(0);
      lenis?.stop();
      document.body.style.overflow = "hidden";
      closeRef.current?.focus();
      return () => {
        lenis?.start();
        document.body.style.overflow = "";
      };
    }
  }, [project, lenis]);

  // Esc to close; basic focus trap around the dialog.
  useEffect(() => {
    if (!project) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
      if (e.key === "ArrowRight") {
        setImageIndex((i) =>
          project.images.length > 0 ? (i + 1) % project.images.length : 0
        );
      }
      if (e.key === "ArrowLeft") {
        setImageIndex((i) =>
          project.images.length > 0
            ? (i - 1 + project.images.length) % project.images.length
            : 0
        );
      }
      if (e.key === "Tab" && dialogRef.current) {
        const focusables = dialogRef.current.querySelectorAll<HTMLElement>(
          "button, [href], [tabindex]:not([tabindex='-1'])"
        );
        if (focusables.length === 0) return;
        const first = focusables[0];
        const last = focusables[focusables.length - 1];
        if (e.shiftKey && document.activeElement === first) {
          e.preventDefault();
          last.focus();
        } else if (!e.shiftKey && document.activeElement === last) {
          e.preventDefault();
          first.focus();
        }
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [project, onClose]);

  const prev = useCallback(() => {
    if (!project) return;
    setImageIndex((i) =>
      project.images.length > 0
        ? (i - 1 + project.images.length) % project.images.length
        : 0
    );
  }, [project]);

  const next = useCallback(() => {
    if (!project) return;
    setImageIndex((i) =>
      project.images.length > 0 ? (i + 1) % project.images.length : 0
    );
  }, [project]);

  if (!project) return null;

  const current = project.images[imageIndex] ?? project.cover;
  const blur = BLUR[current];

  return (
    <div
      className="overlay-enter fixed inset-0 z-[70] flex items-end justify-center bg-navy/60 backdrop-blur-sm sm:items-center sm:p-6"
      role="dialog"
      aria-modal="true"
      aria-label={`${project.title} details`}
      onClick={(e) => {
        if (e.target === e.currentTarget) onClose();
      }}
    >
      <div
        ref={dialogRef}
        className="modal-enter max-h-[92dvh] w-full max-w-3xl overflow-y-auto rounded-card bg-paper shadow-2xl"
      >
        {/* Gallery */}
        <div className="relative bg-navy">
          <div className="relative aspect-[16/10] w-full">
            <Image
              src={current}
              alt={project.captions?.[imageIndex] ?? project.title}
              fill
              sizes="(min-width: 768px) 48rem, 100vw"
              placeholder={blur ? "blur" : undefined}
              blurDataURL={blur}
              className="object-contain"
            />
          </div>
          <button
            ref={closeRef}
            type="button"
            onClick={onClose}
            aria-label="Close details"
            className="absolute right-4 top-4 flex h-10 w-10 items-center justify-center rounded-full bg-white/90 text-ink transition-transform hover:scale-105"
          >
            <X size={18} weight="bold" />
          </button>
          {project.images.length > 1 ? (
            <>
              <button
                type="button"
                onClick={prev}
                aria-label="Previous image"
                className="absolute left-4 top-1/2 flex h-10 w-10 -translate-y-1/2 items-center justify-center rounded-full bg-white/90 text-ink transition-transform hover:scale-105"
              >
                <ArrowLeft size={18} weight="bold" />
              </button>
              <button
                type="button"
                onClick={next}
                aria-label="Next image"
                className="absolute right-4 top-1/2 flex h-10 w-10 -translate-y-1/2 items-center justify-center rounded-full bg-white/90 text-ink transition-transform hover:scale-105"
              >
                <ArrowRight size={18} weight="bold" />
              </button>
              <div className="flex items-center justify-center gap-2 py-3">
                {project.images.map((src, i) => (
                  <button
                    key={src}
                    type="button"
                    aria-label={`Show image ${i + 1} of ${project.images.length}`}
                    aria-current={i === imageIndex}
                    onClick={() => setImageIndex(i)}
                    className={`h-1.5 rounded-full transition-all ${
                      i === imageIndex ? "w-6 bg-white" : "w-1.5 bg-white/40"
                    }`}
                  />
                ))}
              </div>
            </>
          ) : null}
        </div>

        {/* Body */}
        <div className="p-6 sm:p-8">
          <h2 className="font-display text-2xl font-semibold tracking-tight text-ink">
            {project.title}
          </h2>
          {project.meta ? (
            <p className="mt-2 text-sm leading-relaxed text-ink-soft">
              {project.meta}
            </p>
          ) : null}

          {project.specs.length > 0 ? (
            <div className="mt-6">
              {project.specs.map((spec) => (
                <div
                  key={spec.label}
                  className="grid gap-1 border-t border-line py-4 sm:grid-cols-[10rem_1fr] sm:gap-6"
                >
                  <span className="text-[11px] font-bold uppercase tracking-[0.18em] text-ink-soft">
                    {spec.label}
                  </span>
                  <p className="text-sm leading-relaxed text-ink">
                    {spec.value}
                  </p>
                </div>
              ))}
            </div>
          ) : null}

          {project.captions && project.captions.length > 0 ? (
            <ul className="mt-4 space-y-2 border-t border-line pt-4">
              {project.captions.map((c, i) => (
                <li key={c} className="text-sm leading-relaxed text-ink-soft">
                  {i + 1}. {c}
                </li>
              ))}
            </ul>
          ) : null}
        </div>
      </div>
    </div>
  );
}
