import { useState, useEffect } from "react";
import { useGetImageHistory, useDeleteImage, getGetImageHistoryQueryKey } from "@workspace/api-client-react";
import { useQueryClient } from "@tanstack/react-query";
import { motion, AnimatePresence } from "framer-motion";
import {
  Download, Trash2, ImageIcon, Loader2, Lock, Globe,
  Film, Play, Clapperboard,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { useAuth } from "@/contexts/AuthContext";
import { useLang } from "@/contexts/LanguageContext";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";

// ── Types ─────────────────────────────────────────────────────────────────────
interface VideoRecord {
  id: number;
  videoUrl: string;
  thumbnailUrl: string | null;
  prompt: string;
  negativePrompt: string | null;
  model: string;
  aspectRatio: string;
  resolution: string;
  duration: number;
  hasRefImage: boolean;
  isPrivate: boolean;
  userId: number | null;
  createdAt: string;
}

// ── Constants ─────────────────────────────────────────────────────────────────
const BASE = import.meta.env.BASE_URL.replace(/\/$/, "");

const styleLabels: Record<string, string> = {
  none: "無風格", realistic: "寫實", anime: "動漫", artistic: "藝術",
  cartoon: "卡通", sketch: "素描", oil_painting: "油畫",
  watercolor: "水彩", digital_art: "數位藝術",
};

const modelLabels: Record<string, string> = {
  grok: "Grok", meta: "Meta",
  "imagen-pro": "Imagen Pro", "imagen-4": "Imagen 4",
  "imagen-flash": "Imagen Flash",
  "nano-banana-pro": "Nano Banana Pro", "nano-banana-2": "Nano Banana 2",
};

const videoModelLabels: Record<string, string> = {
  "grok-3": "Grok-3", "veo-3-fast": "Veo 3.1 Fast",
};

type FilterTab = "all" | "public" | "private";
type MediaTab = "images" | "videos";

// ── useVideoHistory hook ───────────────────────────────────────────────────────
function useVideoHistory() {
  const [videos, setVideos] = useState<VideoRecord[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetch_ = async () => {
    setIsLoading(true);
    setError(null);
    try {
      const resp = await fetch(`${BASE}/api/videos/history?limit=50`, { credentials: "include" });
      if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
      const data = await resp.json() as { videos: VideoRecord[] };
      setVideos(data.videos || []);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to load");
    } finally {
      setIsLoading(false);
    }
  };

  useEffect(() => { fetch_(); }, []);

  return { videos, isLoading, error, refetch: fetch_ };
}

// ── VideoCard ─────────────────────────────────────────────────────────────────
function VideoCard({ video, onDelete }: { video: VideoRecord; onDelete: (id: number) => void }) {
  const { t } = useLang();
  const [playing, setPlaying] = useState(false);

  const resolveUrl = (url: string) =>
    url.startsWith("/") ? `${BASE}${url}` : url;

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, scale: 0.95 }}
      transition={{ duration: 0.2 }}
      className="bg-card border border-border rounded-xl overflow-hidden group shadow-sm hover:shadow-md transition-shadow"
    >
      {/* Media area */}
      <div className="relative overflow-hidden bg-black" style={{ aspectRatio: video.aspectRatio === "9:16" ? "9/16" : video.aspectRatio === "1:1" ? "1/1" : "16/9" }}>
        {playing ? (
          <video
            src={resolveUrl(video.videoUrl)}
            autoPlay
            controls
            className="w-full h-full object-contain"
            onEnded={() => setPlaying(false)}
          />
        ) : (
          <>
            {video.thumbnailUrl ? (
              <img
                src={resolveUrl(video.thumbnailUrl)}
                alt={video.prompt}
                className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
                loading="lazy"
              />
            ) : (
              <div className="w-full h-full flex items-center justify-center bg-secondary/30">
                <Clapperboard className="w-12 h-12 text-muted-foreground/40" />
              </div>
            )}

            {/* Play overlay */}
            <button
              onClick={() => setPlaying(true)}
              className="absolute inset-0 flex items-center justify-center bg-black/30 opacity-0 group-hover:opacity-100 transition-opacity"
            >
              <div className="w-14 h-14 rounded-full bg-white/20 backdrop-blur-sm border border-white/40 flex items-center justify-center">
                <Play className="w-6 h-6 text-white fill-white ml-1" />
              </div>
            </button>

            {/* Privacy badge */}
            <div className="absolute top-2 left-2">
              {video.isPrivate ? (
                <span className="flex items-center gap-1 px-2 py-0.5 bg-black/60 backdrop-blur-sm rounded-full text-amber-400 text-xs font-medium">
                  <Lock className="w-3 h-3" /> {t.historyTabPrivate}
                </span>
              ) : (
                <span className="flex items-center gap-1 px-2 py-0.5 bg-black/60 backdrop-blur-sm rounded-full text-sky-400 text-xs font-medium">
                  <Globe className="w-3 h-3" /> {t.historyTabPublic}
                </span>
              )}
            </div>

            {/* Model badge */}
            <div className="absolute top-2 right-2">
              <span className="px-2 py-0.5 bg-black/60 backdrop-blur-sm rounded-full text-violet-300 text-xs font-medium">
                {videoModelLabels[video.model] || video.model}
              </span>
            </div>

            {/* Duration badge */}
            <div className="absolute bottom-2 right-2">
              <span className="px-2 py-0.5 bg-black/70 backdrop-blur-sm rounded-full text-white text-xs">
                {video.duration}s
              </span>
            </div>

            {/* Ref image badge */}
            {video.hasRefImage && (
              <div className="absolute bottom-2 left-2">
                <span className="px-2 py-0.5 bg-black/60 backdrop-blur-sm rounded-full text-green-300 text-xs">
                  i2v
                </span>
              </div>
            )}
          </>
        )}
      </div>

      {/* Info + actions */}
      <div className="p-4">
        <p className="text-sm font-medium line-clamp-2 mb-3 h-10 text-foreground" title={video.prompt}>
          {video.prompt}
        </p>
        <div className="flex flex-wrap gap-2 text-xs text-muted-foreground mb-3">
          <span className="px-2 py-1 bg-secondary rounded-md">{video.aspectRatio}</span>
          <span className="px-2 py-1 bg-secondary rounded-md">{video.resolution}</span>
          <span className="px-2 py-1 bg-secondary rounded-md">{video.duration}s</span>
        </div>

        <div className="flex items-center gap-2">
          <a
            href={resolveUrl(video.videoUrl)}
            download={`video-${video.id}.mp4`}
            target="_blank"
            rel="noopener noreferrer"
            className="flex-1"
          >
            <Button variant="outline" size="sm" className="w-full text-xs h-8 gap-1.5">
              <Download className="w-3.5 h-3.5" />
              {t.historyDownload}
            </Button>
          </a>

          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button variant="outline" size="sm" className="h-8 px-2 text-destructive border-destructive/30 hover:bg-destructive/10">
                <Trash2 className="w-3.5 h-3.5" />
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>{t.historyDeleteVidTitle}</AlertDialogTitle>
                <AlertDialogDescription>{t.historyDeleteVidDesc}</AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>{t.poolCancel}</AlertDialogCancel>
                <AlertDialogAction
                  onClick={() => onDelete(video.id)}
                  className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                >
                  {t.historyConfirmDelete}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        </div>
      </div>
    </motion.div>
  );
}

// ── ImageCard ─────────────────────────────────────────────────────────────────
function ImageCard({ img, onDelete, onDownload }: {
  img: any;
  onDelete: (id: number) => void;
  onDownload: (url: string) => void;
}) {
  const { t } = useLang();
  const imgPrivate = (img as any).isPrivate === true;

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, scale: 0.95 }}
      transition={{ duration: 0.2 }}
      className="bg-card border border-border rounded-xl overflow-hidden group shadow-sm hover:shadow-md transition-shadow"
    >
      <div className="relative aspect-square overflow-hidden bg-secondary/50">
        <img
          src={img.imageUrl}
          alt={img.prompt}
          className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
          loading="lazy"
        />
        <div className="absolute top-2 left-2">
          {imgPrivate ? (
            <span className="flex items-center gap-1 px-2 py-0.5 bg-black/60 backdrop-blur-sm rounded-full text-amber-400 text-xs font-medium">
              <Lock className="w-3 h-3" /> {t.historyTabPrivate}
            </span>
          ) : (
            <span className="flex items-center gap-1 px-2 py-0.5 bg-black/60 backdrop-blur-sm rounded-full text-sky-400 text-xs font-medium">
              <Globe className="w-3 h-3" /> {t.historyTabPublic}
            </span>
          )}
        </div>
        <div className="absolute inset-0 bg-background/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-4 backdrop-blur-sm">
          <Button variant="secondary" size="icon" className="h-12 w-12 rounded-full" onClick={() => onDownload(img.imageUrl)}>
            <Download className="h-5 w-5" />
          </Button>
          <AlertDialog>
            <AlertDialogTrigger asChild>
              <Button variant="destructive" size="icon" className="h-12 w-12 rounded-full">
                <Trash2 className="h-5 w-5" />
              </Button>
            </AlertDialogTrigger>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>{t.historyDeleteImgTitle}</AlertDialogTitle>
                <AlertDialogDescription>{t.historyDeleteImgDesc}</AlertDialogDescription>
              </AlertDialogHeader>
              <AlertDialogFooter>
                <AlertDialogCancel>{t.poolCancel}</AlertDialogCancel>
                <AlertDialogAction
                  onClick={() => onDelete(img.id)}
                  className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                >
                  {t.historyConfirmDelete}
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>
        </div>
      </div>
      <div className="p-4">
        <p className="text-sm font-medium line-clamp-2 mb-3 h-10" title={img.prompt}>
          {img.prompt}
        </p>
        <div className="flex flex-wrap gap-2 text-xs text-muted-foreground">
          <span className="px-2 py-1 bg-secondary rounded-md">{styleLabels[img.style] || img.style}</span>
          <span className="px-2 py-1 bg-secondary rounded-md">{img.aspectRatio}</span>
          <span className="px-2 py-1 bg-secondary rounded-md">{modelLabels[img.model] || img.model}</span>
        </div>
      </div>
    </motion.div>
  );
}

// ── History page ───────────────────────────────────────────────────────────────
export function History() {
  const { toast } = useToast();
  const { t } = useLang();
  const queryClient = useQueryClient();
  const { isSignedIn } = useAuth();
  const [mediaTab, setMediaTab] = useState<MediaTab>("images");
  const [filter, setFilter] = useState<FilterTab>("all");

  // ── Image history ──────────────────────────────────────────────────────────
  const { data: imgData, isLoading: imgLoading } = useGetImageHistory(undefined, {
    query: { enabled: true, queryKey: getGetImageHistoryQueryKey() },
  });
  const { mutate: deleteImage } = useDeleteImage();

  const handleDeleteImage = (id: number) => {
    deleteImage({ id }, {
      onSuccess: () => {
        toast({ title: t.historyDeletedImg });
        queryClient.invalidateQueries({ queryKey: getGetImageHistoryQueryKey() });
      },
      onError: () => toast({ variant: "destructive", title: t.historyDeleteFailed }),
    });
  };

  const handleDownloadImage = (url: string) => {
    const a = document.createElement("a");
    a.href = url;
    a.download = "generated-image.png";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };

  // ── Video history ──────────────────────────────────────────────────────────
  const { videos, isLoading: vidLoading, refetch: refetchVideos } = useVideoHistory();

  const handleDeleteVideo = async (id: number) => {
    try {
      const resp = await fetch(`${BASE}/api/videos/${id}`, { method: "DELETE", credentials: "include" });
      if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
      toast({ title: t.historyDeletedVid });
      refetchVideos();
    } catch {
      toast({ variant: "destructive", title: t.historyDeleteFailed });
    }
  };

  // ── Derived lists with filter ──────────────────────────────────────────────
  const allImages = imgData?.images || [];
  const filteredImages = allImages.filter((img) => {
    if (filter === "private") return (img as any).isPrivate === true;
    if (filter === "public") return !(img as any).isPrivate;
    return true;
  });

  const filteredVideos = videos.filter((vid) => {
    if (!isSignedIn) return !vid.isPrivate;
    if (filter === "private") return vid.isPrivate === true;
    if (filter === "public") return !vid.isPrivate;
    return true;
  });

  // ── Filter tabs ────────────────────────────────────────────────────────────
  const filterTabs: { key: FilterTab; label: string }[] = [
    { key: "all",     label: t.historyTabAll },
    { key: "public",  label: t.historyTabPublic },
    { key: "private", label: t.historyTabPrivate },
  ];

  const isLoading = mediaTab === "images" ? imgLoading : vidLoading;
  const isEmpty   = mediaTab === "images" ? allImages.length === 0 : videos.length === 0;

  return (
    <div className="container mx-auto px-4 py-8 max-w-6xl">
      {/* Page header */}
      <div className="mb-6">
        <h1 className="text-3xl font-bold mb-1">{t.navHistory}</h1>
        <p className="text-muted-foreground text-sm">回顧您過往的靈感創作</p>
      </div>

      {/* ── Media type tabs ── */}
      <div className="flex gap-1 mb-5 bg-secondary/50 rounded-xl p-1 w-fit">
        <button
          onClick={() => setMediaTab("images")}
          className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all ${
            mediaTab === "images"
              ? "bg-background text-foreground shadow-sm"
              : "text-muted-foreground hover:text-foreground"
          }`}
        >
          <ImageIcon className="w-4 h-4" />
          {t.historyImages}
          {!imgLoading && allImages.length > 0 && (
            <span className="text-xs bg-primary/20 text-primary px-1.5 py-0.5 rounded-full">
              {allImages.length}
            </span>
          )}
        </button>
        <button
          onClick={() => setMediaTab("videos")}
          className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all ${
            mediaTab === "videos"
              ? "bg-background text-foreground shadow-sm"
              : "text-muted-foreground hover:text-foreground"
          }`}
        >
          <Film className="w-4 h-4" />
          {t.historyVideos}
          {!vidLoading && videos.length > 0 && (
            <span className="text-xs bg-violet-500/20 text-violet-400 px-1.5 py-0.5 rounded-full">
              {videos.length}
            </span>
          )}
        </button>
      </div>

      {/* ── Visibility filter tabs (only when signed in & not empty) ── */}
      {isSignedIn && !isEmpty && (
        <div className="flex gap-2 mb-5">
          {filterTabs.map((tab) => (
            <button
              key={tab.key}
              onClick={() => setFilter(tab.key)}
              className={`px-4 py-1.5 rounded-full text-sm font-medium transition-colors border ${
                filter === tab.key
                  ? "bg-primary text-primary-foreground border-primary"
                  : "bg-secondary text-muted-foreground border-border hover:border-primary/40"
              }`}
            >
              {tab.label}
              {tab.key === "private" && <Lock className="inline ml-1.5 w-3 h-3" />}
            </button>
          ))}
        </div>
      )}

      {/* ── Content ── */}
      <AnimatePresence mode="wait">
        {isLoading ? (
          <motion.div
            key="loading"
            initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}
            className="py-20 flex flex-col items-center justify-center"
          >
            <Loader2 className="w-10 h-10 text-primary animate-spin mb-4" />
            <p className="text-muted-foreground text-sm">
              {mediaTab === "images" ? "載入圖片記錄中..." : t.historyLoadingVideos}
            </p>
          </motion.div>
        ) : isEmpty ? (
          /* Global empty state */
          <motion.div
            key="empty"
            initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0 }}
            className="py-24 flex flex-col items-center justify-center text-center"
          >
            <div className="w-24 h-24 bg-secondary rounded-full flex items-center justify-center mb-6">
              {mediaTab === "images"
                ? <ImageIcon className="w-12 h-12 text-muted-foreground" />
                : <Film className="w-12 h-12 text-muted-foreground" />
              }
            </div>
            <h2 className="text-2xl font-semibold mb-2">
              {mediaTab === "images" ? t.historyEmptyImages : t.historyEmptyVideos}
            </h2>
            <p className="text-muted-foreground max-w-md text-sm">
              {mediaTab === "images" ? t.historyEmptyImagesDesc : t.historyEmptyVideosDesc}
            </p>
          </motion.div>
        ) : mediaTab === "images" ? (
          /* ── Images grid ── */
          <motion.div key="images-grid" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
            {filteredImages.length === 0 ? (
              <div className="py-20 flex flex-col items-center text-center text-muted-foreground">
                <ImageIcon className="w-10 h-10 mb-3 opacity-40" />
                <p className="text-sm">{t.historyNoItemsInFilter}</p>
              </div>
            ) : (
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                <AnimatePresence>
                  {filteredImages.map((img) => (
                    <ImageCard
                      key={img.id}
                      img={img}
                      onDelete={handleDeleteImage}
                      onDownload={handleDownloadImage}
                    />
                  ))}
                </AnimatePresence>
              </div>
            )}
          </motion.div>
        ) : (
          /* ── Videos grid ── */
          <motion.div key="videos-grid" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
            {filteredVideos.length === 0 ? (
              <div className="py-20 flex flex-col items-center text-center text-muted-foreground">
                <Film className="w-10 h-10 mb-3 opacity-40" />
                <p className="text-sm">{t.historyNoItemsInFilter}</p>
              </div>
            ) : (
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                <AnimatePresence>
                  {filteredVideos.map((vid) => (
                    <VideoCard
                      key={vid.id}
                      video={vid}
                      onDelete={handleDeleteVideo}
                    />
                  ))}
                </AnimatePresence>
              </div>
            )}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
