"use client";

import React, { useEffect, useRef, useState } from "react";
import Image from "next/image";
import BoldIcon from "@/components/ui/BoldIcon";
import { captureVideoFrame } from "@/lib/postLocationNotice";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";

type Props = {
  videoUrl: string;
  onCoverChange: (file: File | null) => void;
  initialCoverUrl?: string;
};

export default function VideoCoverPicker({
  videoUrl,
  onCoverChange,
  initialCoverUrl,
}: Props) {
  const { t } = useTranslation("common");
  const videoRef = useRef<HTMLVideoElement>(null);
  const autoCapturedRef = useRef(false);
  const [duration, setDuration] = useState(0);
  const [time, setTime] = useState(0);
  const [coverPreview, setCoverPreview] = useState<string>(initialCoverUrl || "");
  const [mode, setMode] = useState<"frame" | "upload">("frame");

  useEffect(() => {
    autoCapturedRef.current = false;
    setDuration(0);
    setTime(0);
    setMode("frame");
    setCoverPreview(initialCoverUrl || "");
    if (!initialCoverUrl) onCoverChange(null);
    // eslint-disable-next-line react-hooks/exhaustive-deps -- reset cover when video changes
  }, [videoUrl, initialCoverUrl]);

  useEffect(() => {
    return () => {
      if (coverPreview) URL.revokeObjectURL(coverPreview);
    };
  }, [coverPreview]);

  const applyFrameAt = async (seconds: number, silent = false) => {
    const video = videoRef.current;
    if (!video) return false;
    try {
      const blob = await captureVideoFrame(video, seconds);
      const file = new File([blob], `cover-${Date.now()}.webp`, {
        type: "image/webp",
      });
      if (coverPreview?.startsWith("blob:")) URL.revokeObjectURL(coverPreview);
      const preview = URL.createObjectURL(blob);
      setCoverPreview(preview);
      onCoverChange(file);
      setMode("frame");
      if (!silent) toast.success(t("posts.coverSelected"));
      return true;
    } catch {
      if (!silent) toast.error(t("posts.framePickFailed"));
      return false;
    }
  };

  const onUploadCover = (e: React.ChangeEvent<HTMLInputElement>) => {
    const picked = e.target.files?.[0];
    if (!picked || !picked.type.startsWith("image/")) {
      toast.error(t("posts.imagesOnly"));
      return;
    }
    if (coverPreview?.startsWith("blob:")) URL.revokeObjectURL(coverPreview);
    setCoverPreview(URL.createObjectURL(picked));
    onCoverChange(picked);
    setMode("upload");
    toast.success(t("posts.coverUploaded"));
  };

  return (
    <div className="border-t border-neutral-200 p-4 dark:border-neutral-800">
      <p className="mb-3 text-sm font-semibold">{t("posts.videoCover")}</p>

      <div className="mb-3 flex gap-2">
        <button
          type="button"
          onClick={() => setMode("frame")}
          className={`rounded-full px-3 py-1.5 text-xs font-semibold ${
            mode === "frame"
              ? "bg-neutral-900 text-white dark:bg-white dark:text-neutral-900"
              : "bg-neutral-100 text-neutral-600 dark:bg-neutral-800 dark:text-neutral-300"
          }`}
        >
          {t("posts.pickFromVideo")}
        </button>
        <label
          className={`cursor-pointer rounded-full px-3 py-1.5 text-xs font-semibold ${
            mode === "upload"
              ? "bg-neutral-900 text-white dark:bg-white dark:text-neutral-900"
              : "bg-neutral-100 text-neutral-600 dark:bg-neutral-800 dark:text-neutral-300"
          }`}
        >
          {t("posts.uploadCover")}
          <input
            type="file"
            accept="image/*"
            className="hidden"
            onChange={onUploadCover}
          />
        </label>
      </div>

      <div className="relative mb-3 aspect-video overflow-hidden rounded-xl bg-black">
        <video
          ref={videoRef}
          src={videoUrl}
          className="h-full w-full object-contain"
          muted
          playsInline
          preload="metadata"
          onLoadedMetadata={(e) => {
            const d = e.currentTarget.duration || 0;
            setDuration(d);
            setTime(0);
          }}
          onLoadedData={() => {
            if (autoCapturedRef.current || initialCoverUrl) return;
            autoCapturedRef.current = true;
            void applyFrameAt(0.1, true);
          }}
        />
        {coverPreview ? (
          <div className="absolute right-2 top-2 h-16 w-16 overflow-hidden rounded-lg border-2 border-white shadow-lg">
            <Image
              src={coverPreview}
              alt={t("posts.coverAlt")}
              fill
              className="object-cover"
              unoptimized
            />
          </div>
        ) : null}
      </div>

      {mode === "frame" && duration > 0 ? (
        <div className="space-y-2">
          <input
            type="range"
            min={0}
            max={Math.max(0.1, duration - 0.05)}
            step={0.05}
            value={time}
            onChange={(e) => {
              const next = parseFloat(e.target.value);
              setTime(next);
              if (videoRef.current) videoRef.current.currentTime = next;
            }}
            className="w-full accent-[#0095f6]"
          />
          <button
            type="button"
            onClick={() => void applyFrameAt(time)}
            className="flex w-full items-center justify-center gap-2 rounded-xl bg-neutral-100 py-2.5 text-sm font-semibold dark:bg-neutral-800"
          >
            <BoldIcon name="gallery" size={18} className="dark:invert" />
            {t("posts.pickFrameAsCover")}
          </button>
        </div>
      ) : null}
    </div>
  );
}
