import { createSignal, Show, onMount, onCleanup, createMemo } from "solid-js";

const CANVAS_W = 64;
const CANVAS_H = 36;

export interface VideoPlayerProps {
  src: string;
  poster?: string;
  className?: string;
  blurAmount?: number;
  intensity?: number;
}

function formatTime(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
}

export function VideoPlayer(props: VideoPlayerProps) {
  const blurAmount = () => props.blurAmount ?? 60;
  const intensity = () => props.intensity ?? 0.85;

  const [playing, setPlaying] = createSignal(false);
  const [currentTime, setCurrentTime] = createSignal(0);
  const [duration, setDuration] = createSignal(0);
  const [isDragging, setIsDragging] = createSignal(false);
  let videoRef: HTMLVideoElement | undefined;
  let canvasRef: HTMLCanvasElement | undefined;
  let trackRef: HTMLDivElement | undefined;
  let rafId: number;

  const progress = createMemo(() => {
    const dur = duration();
    if (!dur) return 0;
    return (currentTime() / dur) * 100;
  });

  onMount(() => {
    const video = videoRef;
    const canvas = canvasRef;
    if (!video || !canvas) return;

    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    const draw = () => {
      if (!video.paused || video.readyState >= 2) {
        try {
          ctx.drawImage(video, 0, 0, CANVAS_W, CANVAS_H);
        } catch {
          // ignore cross-origin canvas restrictions
        }
      }
      rafId = requestAnimationFrame(draw);
    };

    rafId = requestAnimationFrame(draw);
  });

  onCleanup(() => {
    cancelAnimationFrame(rafId);
  });

  const togglePlay = () => {
    if (!videoRef) return;
    if (videoRef.paused) {
      void videoRef.play();
      setPlaying(true);
    } else {
      videoRef.pause();
      setPlaying(false);
    }
  };

  const onVideoEnded = () => setPlaying(false);

  const onTimeUpdate = () => {
    if (videoRef && !isDragging()) {
      setCurrentTime(videoRef.currentTime);
    }
  };

  const onLoadedMetadata = () => {
    if (videoRef) {
      setDuration(videoRef.duration);
    }
  };

  const seekTo = (clientX: number) => {
    const track = trackRef;
    const video = videoRef;
    if (!track || !video) return;
    const rect = track.getBoundingClientRect();
    const x = clientX - rect.left;
    const pct = Math.max(0, Math.min(1, x / rect.width));
    video.currentTime = pct * duration();
    setCurrentTime(video.currentTime);
  };

  const onTrackMouseDown = (e: MouseEvent) => {
    e.preventDefault();
    setIsDragging(true);
    seekTo(e.clientX);

    const onMouseMove = (ev: MouseEvent) => seekTo(ev.clientX);
    const onMouseUp = () => {
      setIsDragging(false);
      window.removeEventListener("mousemove", onMouseMove);
      window.removeEventListener("mouseup", onMouseUp);
    };
    window.addEventListener("mousemove", onMouseMove);
    window.addEventListener("mouseup", onMouseUp);
  };

  const onTrackTouchStart = (e: TouchEvent) => {
    setIsDragging(true);
    seekTo(e.touches[0].clientX);

    const onTouchMove = (ev: TouchEvent) => seekTo(ev.touches[0].clientX);
    const onTouchEnd = () => {
      setIsDragging(false);
      window.removeEventListener("touchmove", onTouchMove);
      window.removeEventListener("touchend", onTouchEnd);
    };
    window.addEventListener("touchmove", onTouchMove);
    window.addEventListener("touchend", onTouchEnd);
  };

  return (
    <div class={`relative rounded-2xl overflow-hidden bg-canvas border border-border/60 shadow-lg ${props.className ?? ""}`}>
      {/* Ambient glow canvas */}
      <canvas
        ref={(el) => { canvasRef = el; }}
        width={CANVAS_W}
        height={CANVAS_H}
        aria-hidden="true"
        class="absolute pointer-events-none rounded-2xl"
        style={{
          inset: 0,
          width: "100%",
          height: "100%",
          filter: `blur(${blurAmount()}px)`,
          opacity: intensity(),
          transform: "scale(1.08)",
          "z-index": 0,
        }}
      />

      {/* Main video */}
      <div class="relative w-full" style={{ "z-index": 1 }}>
        <video
          ref={(el) => { videoRef = el; }}
          src={props.src}
          poster={props.poster}
          playsinline
          preload="metadata"
          class="w-full block bg-canvas rounded-2xl"
          onEnded={onVideoEnded}
          onClick={togglePlay}
          onTimeUpdate={onTimeUpdate}
          onLoadedMetadata={onLoadedMetadata}
        />

        <button
          onClick={togglePlay}
          aria-label={playing() ? "Pause" : "Play"}
          class="absolute inset-0 w-full h-full bg-transparent cursor-pointer focus:outline-none group"
        >
          <Show when={!playing()}>
            <span
              class="absolute inset-0 flex items-center justify-center pointer-events-none transition-all duration-300"
              style={{ opacity: 1, transform: "none" }}
            >
              <span class="bg-black/40 rounded-full p-4 backdrop-blur-sm group-hover:scale-110 transition-transform">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="32"
                  height="32"
                  viewBox="0 0 24 24"
                  fill="white"
                  stroke="none"
                  aria-hidden="true"
                >
                  <path d="M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" />
                </svg>
              </span>
            </span>
          </Show>

          <Show when={playing()}>
            <span
              class="absolute inset-0 flex items-center justify-center pointer-events-none transition-all duration-300 opacity-0 group-hover:opacity-100"
            >
              <span class="bg-black/40 rounded-full p-4 backdrop-blur-sm">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="32"
                  height="32"
                  viewBox="0 0 24 24"
                  fill="white"
                  stroke="none"
                  aria-hidden="true"
                >
                  <rect x="6" y="4" width="4" height="16" rx="1" />
                  <rect x="14" y="4" width="4" height="16" rx="1" />
                </svg>
              </span>
            </span>
          </Show>
        </button>
      </div>

      {/* Scrubber */}
      <div class="pt-2">
        <div class="w-full">
          <div
            class="relative flex w-full items-center h-10 touch-none cursor-grab select-none"
            onMouseDown={onTrackMouseDown}
            onTouchStart={onTrackTouchStart}
          >
            {/* Current time */}
            <span
              class="absolute left-0 top-0 transition-colors pointer-events-none rounded-md font-medium px-2 py-1 text-xs tabular-nums text-foreground"
              style={{ opacity: 0.8, "background-color": "transparent" }}
            >
              {formatTime(currentTime())}
            </span>
            {/* Duration */}
            <span
              class="absolute right-0 top-0 transition-colors pointer-events-none rounded-md px-2 py-1 text-xs font-medium tabular-nums text-foreground"
              style={{ "background-color": "transparent" }}
            >
              {formatTime(duration())}
            </span>

            {/* Track */}
            <div
              ref={(el) => { trackRef = el; }}
              class="relative w-full overflow-hidden rounded-xl bg-foreground/30"
              style={{ height: "6px", opacity: 0.8 }}
            >
              {/* Fill */}
              <div
                class="absolute left-0 top-0 h-full rounded-xl dark:bg-white bg-black transition-[width] duration-75"
                style={{ width: `${progress()}%` }}
              />
              {/* Buffered / ghost */}
              <div
                class="absolute h-full pointer-events-none rounded-xl"
                style={{ "background-color": "color-mix(in srgb, var(--foreground) 20%, transparent)", left: `${progress()}%`, width: "0px", opacity: 0 }}
              />
            </div>

            {/* Thumb */}
            <span
              class="flex items-center justify-center pointer-events-none absolute top-1/2"
              style={{
                width: "18px",
                height: "18px",
                "margin-top": "-9px",
                left: `${progress()}%`,
                transform: "translateX(-50%)",
                "z-index": 10,
                transition: isDragging() ? "none" : "left 75ms linear",
              }}
            >
              <span
                class="block rounded-xl transition-colors bg-background dark:bg-white"
                style={{ width: "14px", height: "14px" }}
              />
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}
