"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import Image from "next/image";
import Link from "next/link";
import { ReviewPlayer, type ReviewPlayerRef } from "@/components/player/ReviewPlayer";
import { useReviewStore } from "@/hooks/use-review-player";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import {
  Film,
  Loader2,
  CheckCircle2,
  AlertCircle,
  Clock,
  ExternalLink,
} from "lucide-react";

interface Project {
  id: string;
  name: string;
  code: string;
  projectType: string;
}

interface PlaylistVersion {
  id: string;
  versionNumber: number;
  fileUrl: string;
  thumbnailUrl: string | null;
  posterUrl: string | null;
  fps: number;
  approvalStatus: string;
  taskTitle: string;
}

interface PlaylistShot {
  id: string;
  shotCode: string;
  episode: string | null;
  status: string;
  thumbnailUrl: string | null;
  latestVersion: PlaylistVersion;
}

interface PlaylistClientProps {
  projects: Project[];
}

const APPROVAL_COLORS: Record<string, string> = {
  PENDING_REVIEW: "bg-amber-500/10 text-amber-400 border-amber-500/20",
  APPROVED: "bg-emerald-500/10 text-emerald-400 border-emerald-500/20",
  REJECTED: "bg-red-500/10 text-red-400 border-red-500/20",
  NEEDS_CHANGES: "bg-orange-500/10 text-orange-400 border-orange-500/20",
};

const APPROVAL_ICONS: Record<string, React.ElementType> = {
  PENDING_REVIEW: Clock,
  APPROVED: CheckCircle2,
  REJECTED: AlertCircle,
  NEEDS_CHANGES: AlertCircle,
};

export function PlaylistClient({ projects }: PlaylistClientProps) {
  const playerRef = useRef<ReviewPlayerRef>(null);
  const reset = useReviewStore((s) => s.reset);

  const [projectId, setProjectId] = useState<string | null>(null);
  const [shots, setShots] = useState<PlaylistShot[]>([]);
  const [activeShot, setActiveShot] = useState<PlaylistShot | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  // Restore last project from localStorage on mount
  useEffect(() => {
    const saved = localStorage.getItem("playlist:lastProjectId");
    if (saved && projects.some((p) => p.id === saved)) {
      setProjectId(saved);
    }
  }, [projects]);

  // Fetch shots whenever project changes
  useEffect(() => {
    if (!projectId) {
      setShots([]);
      setActiveShot(null);
      return;
    }
    let cancelled = false;
    setIsLoading(true);
    fetch(`/api/playlist?projectId=${projectId}`)
      .then((r) => r.json())
      .then((data) => {
        if (cancelled) return;
        const list: PlaylistShot[] = data.shots ?? [];
        setShots(list);
        // Auto-select the first shot, or keep the current one if it still exists
        setActiveShot((prev) => {
          const stillExists = prev && list.some((s) => s.id === prev.id);
          return stillExists ? prev : (list[0] ?? null);
        });
      })
      .catch(() => {
        if (!cancelled) setShots([]);
      })
      .finally(() => {
        if (!cancelled) setIsLoading(false);
      });
    return () => { cancelled = true; };
  }, [projectId]);

  const handleProjectChange = (id: string) => {
    localStorage.setItem("playlist:lastProjectId", id);
    setProjectId(id);
  };

  const handleSelectShot = useCallback((shot: PlaylistShot) => {
    reset();
    setActiveShot(shot);
  }, [reset]);

  // Group shots by episode for episodic projects
  const selectedProject = projects.find((p) => p.id === projectId);
  const isEpisodic = selectedProject?.projectType === "EPISODIC";

  const episodeGroups: [string, PlaylistShot[]][] = isEpisodic
    ? (() => {
        const map = new Map<string, PlaylistShot[]>();
        for (const shot of shots) {
          const key = shot.episode ?? "(No Episode)";
          if (!map.has(key)) map.set(key, []);
          map.get(key)!.push(shot);
        }
        return Array.from(map.entries());
      })()
    : [];

  return (
    <div className="flex h-full overflow-hidden flex-col">
      {/* Toolbar */}
      <div className="flex items-center gap-4 px-4 py-2.5 border-b border-border bg-card shrink-0">
        <span className="text-sm font-semibold text-white">Playlist</span>
        <div className="flex items-center gap-2">
          <label className="text-xs text-zinc-400 shrink-0">Project:</label>
          <Select value={projectId ?? ""} onValueChange={handleProjectChange}>
            <SelectTrigger className="w-64 h-8 text-sm">
              <SelectValue placeholder="Select a project..." />
            </SelectTrigger>
            <SelectContent>
              {projects.map((p) => (
                <SelectItem key={p.id} value={p.id}>
                  <span className="font-mono text-xs text-zinc-400 mr-2">{p.code}</span>
                  {p.name}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {activeShot && (
          <div className="flex items-center gap-2 ml-auto">
            <span className="font-mono text-sm text-white">{activeShot.shotCode}</span>
            <Badge className={cn("text-xs gap-1", APPROVAL_COLORS[activeShot.latestVersion.approvalStatus])}>
              {(() => {
                const Icon = APPROVAL_ICONS[activeShot.latestVersion.approvalStatus] ?? Clock;
                return <Icon className="h-3 w-3" />;
              })()}
              {activeShot.latestVersion.approvalStatus.replace(/_/g, " ")}
            </Badge>
            <Link
              href={`/review/${activeShot.latestVersion.id}`}
              className="text-zinc-500 hover:text-zinc-200 transition-colors"
              title="Open full review page"
            >
              <ExternalLink className="h-3.5 w-3.5" />
            </Link>
          </div>
        )}
      </div>

      {/* Body: player + shot panel */}
      <div className="flex flex-1 min-h-0 overflow-hidden">
        {/* Player */}
        <div className="flex-1 min-w-0 bg-black flex flex-col">
          {activeShot ? (
            <ReviewPlayer
              key={activeShot.latestVersion.id}
              ref={playerRef}
              videoUrl={activeShot.latestVersion.fileUrl}
              versionId={activeShot.latestVersion.id}
              fps={activeShot.latestVersion.fps}
              comments={[]}
              annotations={[]}
            />
          ) : (
            <div className="flex-1 flex flex-col items-center justify-center gap-3 text-zinc-600">
              <Film className="h-12 w-12 opacity-30" />
              <p className="text-sm">
                {!projectId
                  ? "Select a project to start"
                  : isLoading
                  ? ""
                  : "No shots with video versions found"}
              </p>
              {isLoading && <Loader2 className="h-5 w-5 animate-spin opacity-50" />}
            </div>
          )}
        </div>

        {/* Shot panel */}
        <div className="w-64 xl:w-72 shrink-0 flex flex-col border-l border-border bg-zinc-950 overflow-hidden">
          <div className="px-3 py-2.5 border-b border-border shrink-0 flex items-center justify-between">
            <span className="text-xs font-medium text-zinc-400 uppercase tracking-wider">Shots</span>
            {shots.length > 0 && (
              <span className="text-xs text-zinc-600">{shots.length}</span>
            )}
          </div>

          <div className="flex-1 overflow-y-auto">
            {isLoading ? (
              <div className="flex items-center justify-center py-16 text-zinc-600">
                <Loader2 className="h-5 w-5 animate-spin" />
              </div>
            ) : !projectId ? (
              <div className="flex flex-col items-center justify-center py-16 gap-2 text-zinc-600">
                <Film className="h-7 w-7 opacity-30" />
                <p className="text-xs text-center">Select a project</p>
              </div>
            ) : shots.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-16 gap-2 text-zinc-600">
                <Film className="h-7 w-7 opacity-30" />
                <p className="text-xs text-center">No video versions found</p>
              </div>
            ) : isEpisodic ? (
              <div>
                {episodeGroups.map(([episode, episodeShots]) => (
                  <div key={episode}>
                    <div className="px-3 py-1.5 bg-zinc-900/80 sticky top-0 z-10 border-b border-zinc-800">
                      <span className="text-[10px] font-semibold text-zinc-500 uppercase tracking-wider">
                        Ep {episode}
                      </span>
                    </div>
                    {episodeShots.map((shot) => (
                      <ShotThumbnail
                        key={shot.id}
                        shot={shot}
                        isActive={activeShot?.id === shot.id}
                        onClick={() => handleSelectShot(shot)}
                      />
                    ))}
                  </div>
                ))}
              </div>
            ) : (
              <div>
                {shots.map((shot) => (
                  <ShotThumbnail
                    key={shot.id}
                    shot={shot}
                    isActive={activeShot?.id === shot.id}
                    onClick={() => handleSelectShot(shot)}
                  />
                ))}
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function ShotThumbnail({
  shot,
  isActive,
  onClick,
}: {
  shot: PlaylistShot;
  isActive: boolean;
  onClick: () => void;
}) {
  const thumb = shot.latestVersion.thumbnailUrl ?? shot.latestVersion.posterUrl ?? shot.thumbnailUrl;
  const ApprovalIcon = APPROVAL_ICONS[shot.latestVersion.approvalStatus] ?? Clock;

  return (
    <button
      onClick={onClick}
      className={cn(
        "w-full flex items-start gap-2.5 px-3 py-2.5 text-left transition-colors border-b border-zinc-800/60 group",
        isActive
          ? "bg-blue-500/10 border-l-2 border-l-blue-500"
          : "hover:bg-zinc-800/40 border-l-2 border-l-transparent"
      )}
    >
      {/* Thumbnail */}
      <div className="w-20 aspect-[2.39/1] rounded overflow-hidden bg-zinc-800 shrink-0 flex items-center justify-center">
        {thumb ? (
          <Image
            src={thumb}
            alt={shot.shotCode}
            width={80}
            height={34}
            className="object-cover w-full h-full"
          />
        ) : (
          <Film className="h-4 w-4 text-zinc-600" />
        )}
      </div>

      {/* Info */}
      <div className="flex-1 min-w-0 pt-0.5">
        <p className="font-mono text-xs font-semibold text-white truncate">{shot.shotCode}</p>
        <p className="text-[10px] text-zinc-500 truncate">{shot.latestVersion.taskTitle}</p>
        <div className={cn(
          "flex items-center gap-1 mt-0.5 text-[10px]",
          APPROVAL_COLORS[shot.latestVersion.approvalStatus]?.split(" ").find(c => c.startsWith("text-")) ?? "text-zinc-400"
        )}>
          <ApprovalIcon className="h-2.5 w-2.5 shrink-0" />
          <span className="truncate">
            v{String(shot.latestVersion.versionNumber).padStart(3, "0")}
            {" · "}
            {shot.latestVersion.approvalStatus.replace(/_/g, " ")}
          </span>
        </div>
      </div>
    </button>
  );
}
