// components/BigVideoCard.tsx
import React, { useEffect, useRef, useState } from "react";
import {
  View,
  Text,
  Image,
  TouchableOpacity,
  StyleSheet,
  useWindowDimensions,
  Animated,
} from "react-native";
import Video from "react-native-video";
import { Ionicons } from "@expo/vector-icons";
import { buildDashMpdUri } from "../utils/dash";
import { getPlayUrl, getVideoDetail } from "../services/bilibili";
import { proxyImageUrl } from "../utils/imageUrl";
import { formatCount, formatDuration } from "../utils/format";
import type { VideoItem } from "../services/types";

const HEADERS = {
  Referer: "https://www.bilibili.com",
  "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
};

interface Props {
  item: VideoItem;
  isVisible: boolean;
  onPress: () => void;
}

export function BigVideoCard({ item, isVisible, onPress }: Props) {
  const { width: SCREEN_W } = useWindowDimensions();
  const THUMB_H = SCREEN_W * 0.5625;
  const mediaDimensions = { width: SCREEN_W - 8, height: THUMB_H };

  const [videoUrl, setVideoUrl] = useState<string | undefined>();
  const [isDash, setIsDash] = useState(false);
  const [paused, setPaused] = useState(true);
  const [muted, setMuted] = useState(true);
  const thumbOpacity = useRef(new Animated.Value(1)).current;

  // Reset video state when the item changes
  useEffect(() => {
    setVideoUrl(undefined);
    setIsDash(false);
    setPaused(true);
    setMuted(true);
    thumbOpacity.setValue(1);
  }, [item.bvid]);

  // Fetch play URL when visible for the first time
  useEffect(() => {
    if (!isVisible || videoUrl) return;
    let cancelled = false;
    (async () => {
      try {
        // cid may be missing from feed items; fetch detail if needed
        let cid = item.cid;
        if (!cid) {
          const detail = await getVideoDetail(item.bvid);
          cid = detail.cid ?? detail.pages?.[0]?.cid;
        }
        if (!cid || cancelled) return;
        const playData = await getPlayUrl(item.bvid, cid, 16);
        if (cancelled) return;
        if (playData.dash) {
          if (!cancelled) setIsDash(true);
          try {
            const mpdUri = await buildDashMpdUri(playData, 16);
            if (!cancelled) setVideoUrl(mpdUri);
          } catch {
            if (!cancelled) setVideoUrl(playData.dash.video[0]?.baseUrl);
          }
        } else {
          if (!cancelled) setVideoUrl(playData.durl?.[0]?.url);
        }
      } catch (e) {
        console.warn("BigVideoCard: failed to load play URL", e);
      }
    })();
    return () => {
      cancelled = true;
    };
    // videoUrl intentionally excluded — re-fetch guard prevents redundant fetches after URL is set
  }, [isVisible, item.bvid]);

  // Pause/resume when visibility changes
  useEffect(() => {
    if (!videoUrl) return;
    setPaused(!isVisible);
    if (!isVisible) {
      setMuted(true);
      // Restore thumbnail when leaving viewport
      Animated.timing(thumbOpacity, {
        toValue: 1,
        duration: 150,
        useNativeDriver: true,
      }).start();
    }
  }, [isVisible, videoUrl]);

  const handleVideoReady = () => {
    if (!isVisible) return;
    setPaused(false);
    Animated.timing(thumbOpacity, {
      toValue: 0,
      duration: 300,
      useNativeDriver: true,
    }).start();
  };

  return (
    <TouchableOpacity style={styles.card} onPress={onPress} activeOpacity={0.9}>
      {/* Media area */}
      <View style={[mediaDimensions, { position: "relative" }]}>
        {/* Video player — rendered first so it sits behind the thumbnail */}
        {videoUrl && (
          <Video
            source={
              isDash
                ? { uri: videoUrl, type: "mpd", headers: HEADERS }
                : { uri: videoUrl, headers: HEADERS }
            }
            style={StyleSheet.absoluteFill}
            resizeMode="cover"
            muted={muted}
            paused={paused}
            repeat
            controls={false}
            onReadyForDisplay={handleVideoReady}
          />
        )}

        {/* Thumbnail — on top of Video, fades out once video is ready */}
        <Animated.View
          style={[StyleSheet.absoluteFill, { opacity: thumbOpacity }]}
          pointerEvents="none"
        >
          <Image
            source={{ uri: proxyImageUrl(item.pic) }}
            style={mediaDimensions}
            resizeMode="cover"
          />
        </Animated.View>

        <View style={styles.meta}>
          <Ionicons name="play" size={11} color="#fff" />
          <Text style={styles.metaText}>
            {formatCount(item.stat?.view ?? 0)}
          </Text>
        </View>

        {/* Duration badge on thumbnail */}
        <View style={styles.durationBadge}>
          <Text style={styles.durationText}>
            {formatDuration(item.duration)}
          </Text>
        </View>

        {/* Mute toggle — visible only when video is playing */}
        {videoUrl && !paused && (
          <TouchableOpacity
            style={styles.muteBtn}
            onPress={() => setMuted((m) => !m)}
            activeOpacity={0.7}
          >
            <Ionicons
              name={muted ? "volume-mute" : "volume-high"}
              size={16}
              color="#fff"
            />
          </TouchableOpacity>
        )}
      </View>

      {/* Info */}
      <View style={styles.info}>
        <Text style={styles.title} numberOfLines={2}>
          {item.title}
        </Text>

        <Text style={styles.owner} numberOfLines={1}>
          {item.owner?.name ?? ""}
        </Text>
      </View>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  card: {
    marginHorizontal: 4,
    marginBottom: 6,
    backgroundColor: "#fff",
    borderRadius: 6,
    overflow: "hidden",
  },
  durationBadge: {
    position: "absolute",
    bottom: 4,
    right: 4,
    backgroundColor: "rgba(0,0,0,0.6)",
    borderRadius: 3,
    paddingHorizontal: 4,
    paddingVertical: 1,
    zIndex: 2,
  },
  durationText: { color: "#fff", fontSize: 10 },
  muteBtn: {
    position: "absolute",
    top: 8,
    right: 8,
    backgroundColor: "rgba(0,0,0,0.5)",
    borderRadius: 14,
    width: 28,
    height: 28,
    alignItems: "center",
    justifyContent: "center",
    zIndex: 3,
  },
  info: { padding: 8 },
  title: { fontSize: 14, color: "#212121", lineHeight: 18, marginBottom: 4 },
  meta: {
    position: "absolute",
    bottom: 4,
    left: 4,
    paddingHorizontal: 4,
    borderRadius: 5,
    backgroundColor: "rgba(0,0,0,0.6)",
    flexDirection: "row",
    alignItems: "center",
    paddingVertical: 0,
    gap: 2,
    zIndex: 2,
  },
  metaText: { fontSize: 10, color: "#fff" },
  owner: { fontSize: 11, color: "#999", marginTop: 2 },
});
