import Image from "next/image";
import { useState, useEffect, useRef, useCallback } from "react";
import { createPortal } from "react-dom";

type Props = {
  images: string[];
  videos?: string[];
  title: string;
  expansionHandler: (height: number) => void;
};

// 0 = inline default, 1 = inline enlarged, 2 = fullscreen overlay
type EnlargeLevel = 0 | 1 | 2;

export default function SimpleGallery({
  images,
  videos = [],
  title,
  expansionHandler
}: Props) {

  const [active, setActive] = useState(0);
  const [enlargeLevel, setEnlargeLevel] = useState<EnlargeLevel>(0);
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const videoRef = useRef<HTMLVideoElement | null>(null);

  const totalMedia = images.length + videos.length;
  const isVideo = active >= images.length;
  const videoIndex = active - images.length;
  const currentSrc = isVideo ? videos[videoIndex] : images[active];

  if (totalMedia === 0) return null;

  function scheduleHeightUpdate(enlarged: boolean) {
    if (timerRef.current) clearTimeout(timerRef.current);
    timerRef.current = setTimeout(() => {
      if (!enlarged) {
        expansionHandler(0);
        return;
      }
      const el =
        document.getElementById("gallery-main-image") ??
        document.getElementById("gallery-main-video");       
      if (el){
        let h = el.getBoundingClientRect().height;
        let adjAmount = h + 150;
        expansionHandler(adjAmount);
    }
    }, 200);
  }

  function handleEnlarge() {
    if (enlargeLevel === 0) {
      setEnlargeLevel(1);
      scheduleHeightUpdate(true);
    } else if (enlargeLevel === 1) {
      setEnlargeLevel(2);
    }
  }

  function handleShrink() {
    if (enlargeLevel === 2) {
      setEnlargeLevel(1);
    } else if (enlargeLevel === 1) {
      setEnlargeLevel(0);
      scheduleHeightUpdate(false);
    }
  }

  function handleFullscreenClose() {
    setEnlargeLevel(1);
  }

  function handleThumbnailClick(index: number) {
    setActive(index);
    if (enlargeLevel === 1) {
      scheduleHeightUpdate(true);
    } else if (enlargeLevel === 2) {
      // stay fullscreen with new media
    }
  }

  function expandButton() {
    return (
      <button
        onClick={handleEnlarge}
        title="Enlarge image"
        style={{
          position: "absolute",
          bottom: 8,
          right: 8,
          width: 28,
          height: 28,
          borderRadius: 4,
          border: "none",
          background: "rgba(0,0,0,0.55)",
          color: "#fff",
          cursor: "pointer",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          padding: 0,
          backdropFilter: "blur(4px)",
          transition: "background 0.15s ease",
        }}
        onMouseEnter={(e) =>
          (e.currentTarget.style.background = "rgba(0,0,0,0.8)")
        }
        onMouseLeave={(e) =>
          (e.currentTarget.style.background = "rgba(0,0,0,0.55)")
        }
      >
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M1 5V1H5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
          <path d="M13 9V13H9" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
          <path d="M1 1L5.5 5.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
          <path d="M13 13L8.5 8.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
        </svg>
      </button>
    );
  }

  function shrinkButton() {
    return (
      <button
        onClick={handleShrink}
        title="Shrink image"
        style={{
          position: "absolute",
          top: 8,
          right: 8,
          width: 28,
          height: 28,
          borderRadius: 4,
          border: "none",
          background: "rgba(0,0,0,0.55)",
          color: "#fff",
          cursor: "pointer",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          padding: 0,
          backdropFilter: "blur(4px)",
          zIndex: 1001,
          transition: "background 0.15s ease",
        }}
        onMouseEnter={(e) =>
          (e.currentTarget.style.background = "rgba(0,0,0,0.8)")
        }
        onMouseLeave={(e) =>
          (e.currentTarget.style.background = "rgba(0,0,0,0.55)")
        }
      >
        <svg viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg" width="14" height="14">
          <line x1="15" y1="15" x2="45" y2="45" stroke="white" strokeWidth="6" strokeLinecap="round" />
          <line x1="45" y1="15" x2="15" y2="45" stroke="white" strokeWidth="6" strokeLinecap="round" />
        </svg>
      </button>
    );
  }

  function inlineMedia() {
    const enlarged = enlargeLevel === 1;

    const imageStyle: React.CSSProperties = enlarged ? {
          maxWidth: "100%",
          maxHeight: "90vh",
          height: "auto",
          borderRadius: 6,
          objectFit: "contain",
          boxShadow: "0 8px 40px rgba(0,0,0,0.6)",
          transition: "all 0.3s ease",
        } : {
          width: "100%",
          borderRadius: 4,
          objectFit: "cover",
          maxHeight: 250,
          display: "block",
          transition: "all 0.8s ease",
          zIndex: 1,
        };

    const videoStyle: React.CSSProperties = enlarged ? {
          maxWidth: "100%",
          maxHeight: "90vh",
          objectFit: "contain" as const,
          borderRadius: 6,
          boxShadow: "0 8px 40px rgba(0,0,0,0.6)",
          transition: "all 0.3s ease",
        } : {
          width: "100%",
          borderRadius: 4,
          maxHeight: 250,
          display: "block",
          transition: "all 0.8s ease",
        };

    return (
      <div>
        {isVideo ? (
          <video
            id="gallery-main-video"
            key={currentSrc}
            src={`/${currentSrc}`}
            width={800}
            height={600}
            controls       
            ref={videoRef}
            style={videoStyle}
          />
        ) : (
          <Image
            id="gallery-main-image"
            src={`/${currentSrc}`}
            alt={`${title} screenshot ${active + 1}`}
            width={800}
            height={600}
            style={imageStyle}
          />
        )}

        {enlargeLevel === 0 && expandButton()}
        {enlargeLevel === 1 && (
          <>
            {shrinkButton()}
            {expandButton()}
          </>
        )}
      </div>
    );
  }

  function fullscreenOverlay() {
    if (enlargeLevel !== 2) return null;

    return createPortal(
    <div
      onClick={handleFullscreenClose}
      style={{
        position: "fixed",
        inset: 0,
        background: "rgba(0,0,0,0.85)",
        zIndex: 9999,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        padding: 24,
      }}
    >

        <button
          onClick={handleFullscreenClose}
          title="Close"
          style={{
            position: "fixed",
            top: 16,
            right: 16,
            width: 36,
            height: 36,
            borderRadius: "50%",
            border: "none",
            background: "rgba(255,255,255,0.15)",
            color: "#fff",
            cursor: "pointer",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            backdropFilter: "blur(4px)",
            zIndex: 10000,
            transition: "background 0.15s ease",
          }}
          onMouseEnter={(e) =>
            (e.currentTarget.style.background = "rgba(255,255,255,0.3)")
          }
          onMouseLeave={(e) =>
            (e.currentTarget.style.background = "rgba(255,255,255,0.15)")
          }
        >
          <svg viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg" width="18" height="18">
            <line x1="15" y1="15" x2="45" y2="45" stroke="white" strokeWidth="6" strokeLinecap="round" />
            <line x1="45" y1="15" x2="15" y2="45" stroke="white" strokeWidth="6" strokeLinecap="round" />
          </svg>
        </button>

        {isVideo ? (
          <video
            key={`fs-${currentSrc}`}
            src={`/${currentSrc}`}
            controls
            autoPlay
            onClick={(e) => e.stopPropagation()}
            style={{
              maxWidth: "95vw",
              maxHeight: "90vh",
              borderRadius: 8,
              boxShadow: "0 8px 40px rgba(0,0,0,0.6)",
            }}
          />
        ) : (
          <Image
            src={`/${currentSrc}`}
            alt={`${title} fullscreen ${active + 1}`}
            width={1600}
            height={1200}
            onClick={(e) => e.stopPropagation()}
            style={{
              maxWidth: "95vw",
              maxHeight: "90vh",
              borderRadius: 8,
              objectFit: "contain",
              boxShadow: "0 8px 40px rgba(0,0,0,0.6)",
            }}
          />
        )}
      </div>,
      // portal target
      document.body
    );
  }

  function thumbnailStrip() {
    if (totalMedia <= 1) return null;

    return (
      <div style={{ display: "flex", gap: 6, marginTop: 8, flexWrap: "wrap" }}>
        
        {images.map((src, i) => (
          <Image
            key={`thumb-img-${i}`}
            src={`/${src}`}
            alt={`${title} thumbnail ${i + 1}`}
            width={48}
            height={36}
            onClick={() => handleThumbnailClick(i)}
            style={{
              width: 48,
              height: 36,
              objectFit: "cover",
              borderRadius: 3,
              cursor: "pointer",
              border: `2px solid ${i === active ? "var(--accent)" : "var(--border)"}`,
              opacity: i === active ? 1 : 0.6,
              transition: "all 0.15s ease",
              pointerEvents: "auto",
            }}
          />
        ))}

        {videos.map((_, i) => {
          const mediaIndex = images.length + i;
          const isActive = mediaIndex === active;
          return (
            <button
              key={`thumb-vid-${i}`}
              onClick={() => handleThumbnailClick(mediaIndex)}
              style={{
                width: 48,
                height: 36,
                borderRadius: 3,
                cursor: "pointer",
                border: `2px solid ${isActive ? "var(--accent)" : "var(--border)"}`,
                opacity: isActive ? 1 : 0.6,
                transition: "all 0.15s ease",
                pointerEvents: "auto",
                background: "var(--surface, #1a1a1a)",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                padding: 0,
              }}
            >
              <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M5 3L13 8L5 13V3Z" fill="var(--accent, #888)" />
              </svg>
            </button>
          );
        })}
      </div>
    );
  }

  useEffect(() => {
    return () => {
      if (timerRef.current) clearTimeout(timerRef.current);
    };
  }, []);

  // close fullscreen on Escape
  useEffect(() => {
    if (enlargeLevel === 0) return;
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === "Escape" && enlargeLevel === 2) handleFullscreenClose();
      if (e.key === "Escape" && enlargeLevel === 1) handleShrink();
    }
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, [enlargeLevel]);

  return (
    <>
      <div style={{ marginBottom: 16 }}>
        <div style={{ position: "relative", display: "inline-block", width: "100%" }}>
          {inlineMedia()}
        </div>
        {thumbnailStrip()}
      </div>
      {fullscreenOverlay()}
    </>
  );
}