import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useRef,
  useState,
  type PropsWithChildren,
} from "react";
import { createPortal } from "react-dom";
import { X } from "lucide-react";
import type { Attachment } from "../../../types/post";

type PlayerState = {
  attachment: Attachment;
  currentTime: number;
} | null;

type Ctx = {
  openVideo: (attachment: Attachment, currentTime?: number) => void;
  closeVideo: () => void;
};

const VideoPlayerContext = createContext<Ctx | null>(null);

export function useVideoPlayer(): Ctx {
  const ctx = useContext(VideoPlayerContext);
  if (!ctx)
    throw new Error("useVideoPlayer must be used inside VideoPlayerProvider");
  return ctx;
}

export function VideoPlayerProvider({ children }: PropsWithChildren) {
  const [state, setState] = useState<PlayerState>(null);

  const openVideo = useCallback(
    (attachment: Attachment, currentTime = 0) =>
      setState({ attachment, currentTime }),
    [],
  );
  const closeVideo = useCallback(() => setState(null), []);

  return (
    <VideoPlayerContext.Provider value={{ openVideo, closeVideo }}>
      {children}
      {state ? (
        <PlayerView
          attachment={state.attachment}
          startAt={state.currentTime}
          onClose={closeVideo}
        />
      ) : null}
    </VideoPlayerContext.Provider>
  );
}

function PlayerView({
  attachment,
  startAt,
  onClose,
}: {
  attachment: Attachment;
  startAt: number;
  onClose: () => void;
}) {
  const videoRef = useRef<HTMLVideoElement>(null);

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [onClose]);

  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    if (startAt > 0) v.currentTime = startAt;
    v.play().catch(() => {});
  }, [startAt]);

  return createPortal(
    <div
      className="fixed inset-0 z-[100] flex items-center justify-center bg-black/95"
      onClick={onClose}
      role="dialog"
      aria-modal="true"
    >
      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation();
          onClose();
        }}
        className="absolute right-4 top-4 z-10 flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white transition hover:bg-white/20"
        aria-label="Close"
      >
        <X className="h-5 w-5" />
      </button>
      <video
        ref={videoRef}
        src={attachment.url}
        poster={attachment.posterUrl}
        controls
        playsInline
        className="max-h-[92vh] max-w-[96vw] outline-none"
        onClick={(e) => e.stopPropagation()}
      />
    </div>,
    document.body,
  );
}
