import { memo, useEffect, useState } from 'react'
import { type ViewStyle } from 'react-native'
import { useDerivedValue, useSharedValue } from 'react-native-reanimated'

import {
  Canvas,
  Image as SkiaImage,
  useAnimatedImageValue,
  useImage,
  useVideo
} from "@shopify/react-native-skia";
import { videoUrlCache } from '@/utils/storage'

type Props = {
  url?: string
  needWeb?: boolean
  style?: ViewStyle
  width?: number
  autoplay?: boolean // 控制动画播放，默认 true
}

// 默认宽度256半屏宽度
const VideoBox = ({ url, needWeb = true, width = 256, style, autoplay = true }: Props) => {
  const [urlFinal, setUrlFinal] = useState('')
  const pausedValue = useSharedValue(!autoplay)
  const looping = useSharedValue(true)

  const createUrl = (url: string) => {
    return `https://modal-dev.bowong.cc/api/custom/video/converter/v2?media_url=${encodeURI(url)}&options=compression_level=3,quality=70,loop=true,resolution=${width}x${width},fps=24`
  }

  const isImg = (url: any) => {
    if (!url) return false
    const lowerUrl = url.toLowerCase()
    return lowerUrl?.match(/\.(jpg|jpeg|png|gif|webp|bmp|tiff|svg)(\?.*)?$/i)
  }

  // 检测是否为动画图片（GIF 或动画 WebP）
  const isAnimatedImage = (u?: string | null) => {
    if (!u) return false
    const lowerUrl = u.toLowerCase()
    // GIF 文件通常是动画的
    // WebP 可能是动画的，需要通过内容判断，这里先简单判断扩展名
    return lowerUrl.includes('.gif') || lowerUrl.includes('.webp')
  }

  async function resolveRedirect(url: string) {
    const res = await fetch(url, {
      method: 'GET',
      headers: {
        Range: 'bytes=0-0',
      },
    })
    return res.url
  }

  const setRedirectUrl = async (url?: string) => {
    const isImg2 = isImg(url)
    if (isImg2) {
      setUrlFinal(url!)
      return
    }

    try {
      // 先尝试从缓存获取
      const cachedUrl = await videoUrlCache.get(url!, width)
      // console.log('getRedirectUrl cachedUrl-----------', url, cachedUrl, width)
      if (cachedUrl) {
        setUrlFinal(cachedUrl)
        return
      }

      // 缓存未命中，进行网络请求
      const webpUrl = createUrl(url!)
      const finalUrl = await resolveRedirect(webpUrl)

      // 缓存结果
      await videoUrlCache.set(url!, finalUrl, width)

      // console.log('setRedirectUrl finalUrl-----------', finalUrl)
      setUrlFinal(finalUrl!)
    } catch (error) {
      console.warn('获取视频URL失败:', error)
      // 错误时尝试使用原始URL
      setUrlFinal(url!)
    }
  }

  useEffect(() => {
    if (!url) return
    setRedirectUrl(url!)
    // const finalUrl = createUrl(url)
    return
  }, [url])

  // 控制动画播放/停止
  useEffect(() => {
    pausedValue.value = !autoplay
  }, [autoplay, pausedValue])

  if (!url) return null

  // 本地文件全部用 video 组件播放
  const isLocal = url ? !url.startsWith('http://') && !url.startsWith('https://') : false
  const isImageFile = url ? isImg(url) : false

  // 仅当明显是视频地址时才交给 Skia Video 处理，防止非视频资源导致原生 HostFunction 崩溃
  const isVideoUrl = (u?: string | null) => {
    if (!u) return false
    const lowerUrl = u.toLowerCase()
    // 目前 Skia Video 只对常见视频格式稳定，这里做一次白名单过滤
    return lowerUrl.includes('.mp4') || lowerUrl.includes('.mov') || lowerUrl.includes('.m4v') || lowerUrl.includes('.webm')
  }

  // 获取实际使用的URL
  // 对于本地文件，直接使用 url
  // 对于远程文件，需要等待 urlFinal 准备好（图片文件除外，因为图片不需要转换）
  const displayUrl = url
    ? isLocal
      ? url
      : isImageFile
        ? url // 图片文件直接使用原始 URL
        : urlFinal || null // 视频文件需要等待转换后的 URL
    : null

  // 判断是否为图片（需要检查原始 URL 和最终 URL）
  const shouldUseImage = isImageFile || (displayUrl ? isImg(displayUrl) : false)

  // 判断是否为动画图片
  const shouldUseAnimatedImage = shouldUseImage && isAnimatedImage(displayUrl)

  // 判断是否为静态图片
  const shouldUseStaticImage = shouldUseImage && !shouldUseAnimatedImage

  // 只有在明确是视频链接且不是图片时才调用 useVideo，避免触发 Skia.Video 原生异常
  const shouldUseVideo = !shouldUseImage && isVideoUrl(displayUrl)

  // Hooks 必须在顶层调用，不能条件调用
  // 对于静态图片，使用 useImage
  // 对于动画图片，使用 useAnimatedImageValue（支持 autoplay 控制）
  // 对于视频，使用 useVideo
  // 如果 displayUrl 为 null，hooks 会返回 null
  const staticImage = useImage(shouldUseStaticImage ? displayUrl : null)
  const animatedImage = useAnimatedImageValue(
    shouldUseAnimatedImage ? displayUrl : null,
    shouldUseAnimatedImage ? pausedValue : undefined
  )
  const videoResult = useVideo(
    shouldUseVideo ? displayUrl : null,
    {
      paused: pausedValue,
      looping,
    }
  )

  // 使用 useDerivedValue 从 videoResult.currentFrame 获取当前帧
  // 如果 videoResult 为 null，videoFrame 也会是 null
  const videoFrame = useDerivedValue(() => {
    return videoResult?.currentFrame.value ?? null
  })

  if (!url || !displayUrl) return null

  const canvasStyle = style || {}
  const canvasWidth = (canvasStyle.width as number) || width
  const canvasHeight = (canvasStyle.height as number) || width

  // 如果是静态图片且已加载
  if (shouldUseStaticImage && staticImage) {
    return (
      <Canvas style={[{ width: canvasWidth, height: canvasHeight }, canvasStyle]}>
        <SkiaImage
          image={staticImage}
          x={0}
          y={0}
          width={canvasWidth}
          height={canvasHeight}
          fit="cover"
        />
      </Canvas>
    )
  }

  // 如果是动画图片（GIF 或动画 WebP）
  if (shouldUseAnimatedImage && animatedImage) {
    return (
      <Canvas style={[{ width: canvasWidth, height: canvasHeight }, canvasStyle]}>
        <SkiaImage
          image={animatedImage}
          x={0}
          y={0}
          width={canvasWidth}
          height={canvasHeight}
          fit="cover"
        />
      </Canvas>
    )
  }

  // 如果是视频，使用 currentFrame SharedValue
  if (shouldUseVideo && videoResult && videoFrame) {
    return (
      <Canvas style={[{ width: canvasWidth, height: canvasHeight }, canvasStyle]}>
        <SkiaImage
          image={videoFrame}
          x={0}
          y={0}
          width={canvasWidth}
          height={canvasHeight}
          fit="cover"
        />
      </Canvas>
    )
  }

  return null
}

export default memo(VideoBox)
