import { useState, useEffect, useRef } from "react";
import { useParams, useNavigate } from "react-router";
import {
  Loader2, Play, Pause, Download, Trash2, Edit2,
  SkipBack, SkipForward, Check, Film,
} from "lucide-react";
import {
  useVideoTasks,
  useEpisodes,
  useStoryboards,
  useAssemblyTask,
  useStartAssembly,
  useDeleteVideoTask,
} from "../../hooks/useAi";
import type { AiTask, Episode, Storyboard } from "../../lib/api/ai";

function fmt(secs: number) {
  const m = Math.floor(secs / 60);
  const s = secs % 60;
  return `${m}:${String(s).padStart(2, "0")}`;
}
function timeAgo(dateStr: string) {
  const diff = Date.now() - new Date(dateStr).getTime();
  const h = Math.floor(diff / 3600000);
  if (h < 1) return "刚刚";
  if (h < 24) return `${h}小时前`;
  return `${Math.floor(h / 24)}天前`;
}

export function VideoGeneration() {
  const { projectId } = useParams<{ projectId: string }>();
  const navigate = useNavigate();
  const pid = projectId ?? "";

  const { data: episodes = [], isLoading: epLoading } = useEpisodes(pid);
  const { data: allTasks = [] } = useVideoTasks(pid);

  const [activeEpId, setActiveEpId] = useState<string>("");

  useEffect(() => {
    if (episodes.length > 0 && !activeEpId) {
      setActiveEpId(episodes[0].id);
    }
  }, [episodes.length]);

  const { data: storyboards = [] } = useStoryboards(pid, activeEpId);
  const { data: assemblyTask } = useAssemblyTask(pid, activeEpId);
  const startAssembly = useStartAssembly(pid, activeEpId);
  const deleteTask = useDeleteVideoTask(pid);

  // Tasks for active episode
  const epTasks = allTasks.filter((t) => t.episodeId === activeEpId);

  const getTaskForSb = (sb: Storyboard): AiTask | undefined => {
    const byId = epTasks.filter((t) => t.storyboardId === sb.id);
    return byId.find((t) => t.status === "succeeded")
      ?? byId.find((t) => t.status === "running" || t.status === "submitted" || t.status === "pending")
      ?? byId[0];
  };

  // Succeeded shots in sequence order
  const orderedShots = storyboards
    .map((sb) => ({ sb, task: getTaskForSb(sb) }))
    .filter(({ task }) => task?.status === "succeeded" && task.resultVideoUrl);

  // Stats
  const totalShots = storyboards.length;
  const doneShots = orderedShots.length;
  const pendingShots = epTasks.filter(
    (t) => t.status === "pending" || t.status === "submitted" || t.status === "running"
  ).length;
  // Use actual storyboard durationSeconds (updated when video is generated)
  const totalDuration = storyboards.reduce((s, sb) => s + (sb.durationSeconds || 0), 0);

  // ─── Player state ───
  // "assembly" = show assembled video, "shot" = show individual storyboard video
  const videoRef = useRef<HTMLVideoElement>(null);
  const [playing, setPlaying] = useState(false);
  const [playerMode, setPlayerMode] = useState<"assembly" | "shot">("assembly");
  const [currentShotIdx, setCurrentShotIdx] = useState(0);

  const hasAssembly = assemblyTask?.status === "succeeded" && !!assemblyTask.downloadUrl;

  // Current video URL to show in player
  const currentVideoUrl = playerMode === "assembly" && hasAssembly
    ? assemblyTask!.downloadUrl!
    : orderedShots[currentShotIdx]?.task?.resultVideoUrl ?? null;

  const currentShotLabel = playerMode === "shot"
    ? `分镜 ${String(orderedShots[currentShotIdx]?.sb.sequenceNum ?? 1).padStart(3, "0")}`
    : "整集";

  // Sync video src when currentVideoUrl changes
  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    v.pause();
    setPlaying(false);
    v.load();
  }, [currentVideoUrl]);

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

  const selectShot = (idx: number) => {
    setCurrentShotIdx(idx);
    setPlayerMode("shot");
  };

  const handleDelete = async (taskId: string) => {
    if (!confirm("确定删除此视频？")) return;
    await deleteTask.mutateAsync(taskId);
  };

  // Episode stats helper
  const epShotCount = (ep: Episode) => ep.storyboardCount ?? 0;
  const epDoneCount = (ep: Episode) =>
    allTasks.filter((t) => t.episodeId === ep.id && t.status === "succeeded").length;

  return (
    <div className="h-full flex overflow-hidden bg-background">

      {/* ─── Left: Episode list ─── */}
      <div className="flex-shrink-0 border-r border-border flex flex-col" style={{ width: 180 }}>
        <div className="h-14 px-4 border-b border-border flex items-center flex-shrink-0">
          <span className="text-sm font-medium text-foreground">选集</span>
        </div>
        <div className="flex-1 overflow-y-auto py-2">
          {epLoading ? (
            <div className="flex justify-center pt-6">
              <Loader2 className="w-4 h-4 animate-spin text-muted-foreground" />
            </div>
          ) : episodes.length === 0 ? (
            <p className="text-xs text-muted-foreground text-center pt-6 px-3">暂无分集</p>
          ) : (
            episodes.map((ep) => {
              const total = epShotCount(ep);
              const done = epDoneCount(ep);
              const isActive = ep.id === activeEpId;
              return (
                <button
                  key={ep.id}
                  onClick={() => { setActiveEpId(ep.id); setPlayerMode("assembly"); setCurrentShotIdx(0); }}
                  className={`w-full text-left px-4 py-3 border-b border-border/50 transition-colors ${
                    isActive ? "bg-accent" : "hover:bg-muted"
                  }`}
                >
                  <div className="flex items-center justify-between mb-0.5">
                    <span className={`text-sm font-semibold ${isActive ? "text-primary" : "text-foreground"}`}>
                      第{ep.episodeNumber}集
                    </span>
                    {isActive && <Check className="w-3.5 h-3.5 text-primary" />}
                  </div>
                  <div className="flex items-center justify-between">
                    <span className="text-[11px] text-muted-foreground">{total}个分镜</span>
                    <span className={`text-[11px] ${done > 0 ? "text-green-600" : "text-muted-foreground"}`}>
                      {done}/{total}完成
                    </span>
                  </div>
                </button>
              );
            })
          )}
        </div>
      </div>

      {/* ─── Right: Main content ─── */}
      <div className="flex-1 overflow-y-auto">
        <div className="p-6 space-y-6">

          {/* Section 1: 视频播放器 */}
          <div>
            <div className="flex items-center justify-between mb-1">
              <div>
                <h2 className="text-lg font-semibold text-foreground">整集视频</h2>
                <p className="text-xs text-muted-foreground">点击下方分镜缩略图可切换单镜预览</p>
              </div>
              <div className="flex items-center gap-2">
                {/* Assembly controls */}
                {hasAssembly && (
                  <button
                    onClick={() => setPlayerMode("assembly")}
                    className={`flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-xs transition ${
                      playerMode === "assembly"
                        ? "bg-primary text-primary-foreground"
                        : "border border-border text-foreground hover:bg-muted"
                    }`}
                  >
                    <Film className="w-3.5 h-3.5" />
                    整集
                  </button>
                )}
                {(!assemblyTask || assemblyTask.status === "failed") && (
                  <button
                    onClick={() => startAssembly.mutate()}
                    disabled={startAssembly.isPending || doneShots === 0}
                    className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg border border-border text-xs text-foreground hover:bg-muted transition disabled:opacity-50"
                  >
                    {startAssembly.isPending ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Film className="w-3.5 h-3.5" />}
                    合成整集
                  </button>
                )}
                {(assemblyTask?.status === "running" || assemblyTask?.status === "pending") && (
                  <span className="flex items-center gap-1.5 px-3 py-1.5 text-xs text-muted-foreground">
                    <Loader2 className="w-3.5 h-3.5 animate-spin" />合成中...
                  </span>
                )}
                {hasAssembly && (
                  <a
                    href={assemblyTask!.downloadUrl!}
                    target="_blank"
                    rel="noreferrer"
                    className="flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-green-600 text-white text-xs hover:bg-green-700 transition"
                  >
                    <Download className="w-3.5 h-3.5" />
                    导出整集
                  </a>
                )}
              </div>
            </div>

            {/* Player */}
            <div className="rounded-xl overflow-hidden bg-black relative" style={{ aspectRatio: "16/9", maxHeight: 440 }}>
              {currentVideoUrl ? (
                <>
                  {/* Badge */}
                  <div className="absolute top-3 left-3 z-10 bg-black/60 text-white text-xs px-2.5 py-1.5 rounded-lg backdrop-blur-sm">
                    <div className="text-[10px] opacity-70 leading-none mb-0.5">
                      {playerMode === "assembly" ? "整集合成" : "分镜预览"}
                    </div>
                    <div className="font-medium">{currentShotLabel}</div>
                  </div>
                  {/* Duration badge */}
                  <div className="absolute top-3 right-3 z-10 bg-black/60 text-white text-xs px-2.5 py-1.5 rounded-lg backdrop-blur-sm font-mono">
                    {fmt(totalDuration)}
                  </div>
                  <video
                    ref={videoRef}
                    src={currentVideoUrl}
                    className="w-full h-full object-contain"
                    onPlay={() => setPlaying(true)}
                    onPause={() => setPlaying(false)}
                    onEnded={() => {
                      setPlaying(false);
                      // Auto-advance to next shot in shot mode
                      if (playerMode === "shot" && currentShotIdx < orderedShots.length - 1) {
                        setCurrentShotIdx((i) => i + 1);
                      }
                    }}
                  />
                  {/* Play/Pause overlay */}
                  <button
                    onClick={togglePlay}
                    className="absolute inset-0 flex items-center justify-center group"
                  >
                    <div className={`w-14 h-14 rounded-full bg-white/20 backdrop-blur-sm flex items-center justify-center group-hover:bg-white/30 transition ${playing ? "opacity-0 group-hover:opacity-100" : ""}`}>
                      {playing
                        ? <Pause className="w-7 h-7 text-white" />
                        : <Play className="w-7 h-7 text-white ml-0.5" />}
                    </div>
                  </button>
                </>
              ) : (
                <div className="w-full h-full flex flex-col items-center justify-center gap-3">
                  <Film className="w-12 h-12 text-white/20" />
                  <p className="text-sm text-white/50">
                    {assemblyTask?.status === "running" || assemblyTask?.status === "pending"
                      ? "整集视频合成中..."
                      : doneShots === 0
                        ? "暂无已完成的分镜视频"
                        : "整集视频尚未合成"}
                  </p>
                </div>
              )}
            </div>

            {/* Controls row */}
            <div className="flex items-center gap-3 mt-3">
              <button
                onClick={() => {
                  const idx = Math.max(0, currentShotIdx - 1);
                  selectShot(idx);
                }}
                disabled={orderedShots.length === 0 || (playerMode === "shot" && currentShotIdx === 0)}
                className="p-1.5 rounded-lg hover:bg-muted transition text-muted-foreground disabled:opacity-30"
              >
                <SkipBack className="w-4 h-4" />
              </button>
              <button
                onClick={togglePlay}
                disabled={!currentVideoUrl}
                className="w-8 h-8 rounded-full bg-primary flex items-center justify-center hover:bg-primary/90 transition disabled:opacity-40"
              >
                {playing
                  ? <Pause className="w-4 h-4 text-primary-foreground" />
                  : <Play className="w-4 h-4 text-primary-foreground ml-0.5" />}
              </button>
              <button
                onClick={() => {
                  const idx = Math.min(orderedShots.length - 1, currentShotIdx + 1);
                  selectShot(idx);
                }}
                disabled={orderedShots.length === 0 || (playerMode === "shot" && currentShotIdx >= orderedShots.length - 1)}
                className="p-1.5 rounded-lg hover:bg-muted transition text-muted-foreground disabled:opacity-30"
              >
                <SkipForward className="w-4 h-4" />
              </button>
              <span className="text-xs text-muted-foreground ml-1">
                {playerMode === "shot" && orderedShots.length > 0
                  ? `${currentShotIdx + 1} / ${orderedShots.length}`
                  : `共 ${orderedShots.length} 个分镜`}
              </span>
            </div>

            {/* Thumbnail strip — click to switch player to that shot */}
            {orderedShots.length > 0 && (
              <div className="flex gap-2 mt-3 overflow-x-auto pb-1">
                {orderedShots.map(({ sb, task }, i) => (
                  <button
                    key={sb.id}
                    onClick={() => selectShot(i)}
                    className={`flex-shrink-0 relative rounded-lg overflow-hidden border-2 transition ${
                      playerMode === "shot" && currentShotIdx === i
                        ? "border-primary"
                        : "border-transparent hover:border-border"
                    }`}
                    style={{ width: 100, aspectRatio: "16/9" }}
                  >
                    <video
                      src={task!.resultVideoUrl!}
                      className="w-full h-full object-cover"
                      muted
                    />
                    <div className="absolute bottom-0 left-0 right-0 flex items-end justify-between px-1.5 py-1 bg-gradient-to-t from-black/70">
                      <span className="text-[10px] text-white font-medium">{String(sb.sequenceNum).padStart(3, "0")}</span>
                      <span className="text-[10px] text-white/80">{sb.durationSeconds}s</span>
                    </div>
                  </button>
                ))}
              </div>
            )}
          </div>

          {/* Section 2: Stats */}
          <div className="grid grid-cols-4 gap-4">
            {[
              { label: "总分镜数", value: totalShots, color: "text-foreground" },
              { label: "已完成", value: doneShots, color: "text-green-600" },
              { label: "生成中", value: pendingShots, color: "text-orange-500" },
              { label: "总时长", value: fmt(totalDuration), color: "text-foreground" },
            ].map((s) => (
              <div key={s.label} className="rounded-xl border border-border bg-card p-4">
                <div className={`text-2xl font-bold mb-1 ${s.color}`}>{s.value}</div>
                <div className="text-xs text-muted-foreground">{s.label}</div>
              </div>
            ))}
          </div>

          {/* Section 3: 分镜管理 */}
          <div>
            <h3 className="text-base font-semibold text-foreground mb-4">分镜管理</h3>
            {storyboards.length === 0 ? (
              <div className="text-center py-12 text-sm text-muted-foreground">
                {!activeEpId ? "请从左侧选择集数" : "该集暂无分镜"}
              </div>
            ) : (
              <div className="grid grid-cols-3 gap-4">
                {storyboards.map((sb) => {
                  const task = getTaskForSb(sb);
                  const hasVideo = task?.status === "succeeded" && task.resultVideoUrl;
                  const isPending = task?.status === "pending" || task?.status === "submitted" || task?.status === "running";
                  return (
                    <div key={sb.id} className="rounded-xl border border-border bg-card overflow-hidden">
                      {/* Thumbnail — click plays in top player */}
                      <button
                        className="relative bg-black w-full"
                        style={{ aspectRatio: "16/9" }}
                        onClick={() => {
                          if (!hasVideo) return;
                          const idx = orderedShots.findIndex((s) => s.sb.id === sb.id);
                          if (idx >= 0) selectShot(idx);
                          window.scrollTo({ top: 0, behavior: "smooth" });
                        }}
                      >
                        {hasVideo ? (
                          <video
                            src={task!.resultVideoUrl!}
                            className="w-full h-full object-cover"
                            muted
                          />
                        ) : isPending ? (
                          <div className="w-full h-full flex flex-col items-center justify-center gap-1">
                            <Loader2 className="w-6 h-6 animate-spin text-white/40" />
                            <span className="text-[10px] text-white/40">生成中</span>
                          </div>
                        ) : (
                          <div className="w-full h-full flex items-center justify-center">
                            <Play className="w-8 h-8 text-white/20" />
                          </div>
                        )}
                        {/* Badges */}
                        <div className="absolute top-2 left-2 bg-black/60 text-white text-[11px] font-medium px-1.5 py-0.5 rounded backdrop-blur-sm">
                          分镜 {String(sb.sequenceNum).padStart(3, "0")}
                        </div>
                        {sb.durationSeconds > 0 && (
                          <div className="absolute top-2 right-2 bg-black/60 text-white text-[11px] px-1.5 py-0.5 rounded backdrop-blur-sm">
                            {sb.durationSeconds}s
                          </div>
                        )}
                        {hasVideo && <div className="absolute bottom-2 right-2 w-2 h-2 rounded-full bg-green-400" />}
                        {isPending && <div className="absolute bottom-2 right-2 w-2 h-2 rounded-full bg-orange-400 animate-pulse" />}
                        {/* Play hint overlay */}
                        {hasVideo && (
                          <div className="absolute inset-0 bg-black/0 hover:bg-black/20 flex items-center justify-center opacity-0 hover:opacity-100 transition">
                            <Play className="w-8 h-8 text-white drop-shadow" />
                          </div>
                        )}
                      </button>

                      {/* Footer */}
                      <div className="px-3 py-2.5 flex items-center justify-between">
                        <span className="text-[11px] text-muted-foreground">
                          {task ? timeAgo(task.createdAt) : "未生成"}
                        </span>
                        <div className="flex items-center gap-3">
                          <button
                            onClick={() => navigate(`/project/${pid}/storyboard/${activeEpId}`)}
                            className="flex items-center gap-1 text-[11px] text-primary hover:underline"
                          >
                            <Edit2 className="w-3 h-3" />
                            编辑
                          </button>
                          {hasVideo && (
                            <a
                              href={task!.resultVideoUrl!}
                              target="_blank"
                              rel="noreferrer"
                              className="flex items-center gap-1 text-[11px] text-foreground hover:text-primary"
                            >
                              <Download className="w-3 h-3" />
                              下载
                            </a>
                          )}
                          {task && (
                            <button
                              onClick={() => handleDelete(task.id)}
                              disabled={deleteTask.isPending}
                              className="text-destructive hover:text-red-700 disabled:opacity-40"
                            >
                              <Trash2 className="w-3.5 h-3.5" />
                            </button>
                          )}
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>

        </div>
      </div>
    </div>
  );
}
