import React, { memo, useMemo } from 'react'
import { Pressable } from 'react-native'
import {
  Canvas,
  Image as SkiaImage,
  Group,
  LinearGradient,
  Paragraph,
  Path,
  Rect,
  Skia,
  useAnimatedImageValue,
  useImage,
  useFonts,
  vec,
} from '@shopify/react-native-skia'
import { Block } from '@share/components'
import ParallelogramShadow from './ParallelogramShadow'

type MediaItem = {
  id: string
  url: string
  webpPreviewUrl?: string
  authorName?: string
  likeCount?: number
  title?: string
}

type Props = {
  item: MediaItem
  isSelected: boolean
  itemWidth: number
  isVisible: boolean
  onSelect: () => void
  /** 是否使用 WebP 格式，默认 true */
  isWebP?: boolean
  /** 图片压缩宽度，默认 256 */
  compressionWidth?: number
  /** 是否启用压缩，默认 false（如果 webpPreviewUrl 已存在，通常不需要再次压缩） */
  isCompression?: boolean
  /** 错误占位图 URL 或本地资源 */
  errorSource?: string | number
  /** 自定义缓存键，用于需要重定向的 URL */
  cacheKey?: string
}

// Cloudflare 图片优化服务
const IMAGE_OPTIMIZATION_BASE = 'https://bowong.cc/cdn-cgi/image'

const ParallelogramGridItem = memo<Props>(function ParallelogramGridItem({
  item,
  isSelected,
  itemWidth,
  isVisible,
  onSelect,
  isWebP = true,
  compressionWidth = 256,
  isCompression = false,
  errorSource,
  cacheKey,
}) {
  const isNetworkImage = (uri: string | number): boolean => {
    if (typeof uri !== 'string') return false
    return uri.startsWith('http://') || uri.startsWith('https://')
  }

  const getCompressionUrl = (url: string): string => {
    const format = isWebP ? 'webp' : 'jpg'
    return `${IMAGE_OPTIMIZATION_BASE}/width=${compressionWidth},quality=75,format=${format}/${url}`
  }

  // 优先级处理：webpPreviewUrl > url > errorSource
  const imageSource = useMemo(() => {
    if (item.webpPreviewUrl) {
      const source = item.webpPreviewUrl
      if (isNetworkImage(source) && isCompression) {
        return getCompressionUrl(source)
      }
      return source
    }

    if (item.url) {
      const source = item.url
      if (isNetworkImage(source) && isCompression) {
        return getCompressionUrl(source)
      }
      return source
    }

    return null
  }, [item.webpPreviewUrl, item.url, isCompression, isWebP, compressionWidth])

  // 使用 useAnimatedImageValue 加载主图片（支持 GIF 和动画 WebP）
  const skiaImage = useAnimatedImageValue(imageSource || null)
  const errorImage = useImage(errorSource || null)

  // 最终使用的图片：主图片优先，失败时使用错误占位图
  const displayImage = useMemo(() => {
    if (skiaImage) {
      return skiaImage
    }
    return errorImage || null
  }, [skiaImage, errorImage])

  const labelHeight = 24
  const cardHeight = itemWidth + labelHeight
  // 预留给外部阴影的额外画布高度，避免阴影被裁剪
  const shadowMargin = 4

  // 平行四边形路径（只裁剪内容，不拉伸内容）
  const skewOffset = 8
  const padding = 2 // 四周内缩，避免描边被裁掉

  // 外层（黑色）边框 & 裁剪路径
  const parallelogramPath = useMemo(() => {
    const p = Skia.Path.Make()
    p.moveTo(skewOffset + padding, padding)
    p.lineTo(itemWidth - padding, padding)
    p.lineTo(itemWidth - skewOffset - padding, cardHeight - padding)
    p.lineTo(padding, cardHeight - padding)
    p.close()
    return p
  }, [cardHeight, itemWidth])

  const fontMgr = useFonts({
    System: [],
  })

  const authorParagraph = useMemo(() => {
    if (!fontMgr) return null
    const builder = Skia.ParagraphBuilder.Make(
      {
        textAlign: 0,
      },
      fontMgr,
    )

    builder.pushStyle({
      color: Skia.Color('#323232'),
      fontSize: 10,
      fontFamilies: ['System'],
      fontStyle: { weight: 400 },
    })
    builder.addText(item.authorName || '未知作者')

    const para = builder.build()
    para.layout(40)
    return para
  }, [fontMgr, item.authorName])

  const likeParagraph = useMemo(() => {
    if (!fontMgr) return null
    const builder = Skia.ParagraphBuilder.Make(
      {
        textAlign: 0,
      },
      fontMgr,
    )
    builder.pushStyle({
      color: Skia.Color('#FF0000'),
      fontSize: 8,
      fontFamilies: ['System'],
      fontStyle: { weight: 900 },
    })
    builder.addText('❤ ')

    builder.pushStyle({
      color: Skia.Color('#323232'),
      fontSize: 10,
      fontFamilies: ['System'],
      fontStyle: { weight: 400 },
    })
    builder.addText(String(item.likeCount ?? 0))

    const para = builder.build()
    para.layout(40)
    return para
  }, [fontMgr, item.likeCount])

  return (
    <Pressable
      onPress={onSelect}
      style={{
        marginBottom: 12,
        width: itemWidth,
        height: cardHeight,
      }}
    >
      <Block style={{ width: itemWidth, height: cardHeight + shadowMargin, position: 'relative' }}>
        <Canvas style={{ width: itemWidth, height: cardHeight + shadowMargin, position: 'absolute' }}>
          <Group clip={parallelogramPath}>
            {isVisible && displayImage && (
              <SkiaImage
                image={displayImage}
                x={0}
                y={0}
                width={itemWidth}
                height={itemWidth}
                fit="cover"
              />
            )}

            <LinearGradient
              start={vec(0, itemWidth)}
              end={vec(0, itemWidth * 0.6)}
              colors={['rgba(0,0,0,0.8)', 'transparent']}
            />

            <Rect
              x={0}
              y={itemWidth}
              width={itemWidth}
              height={labelHeight}
              color={isSelected ? '#FFE500' : '#FFFFFF'}
            />

            {!isSelected && (
              <Rect
                x={0}
                y={itemWidth}
                width={itemWidth}
                height={1}
                color="#323232"
              />
            )}

            {authorParagraph && (
              <Paragraph
                paragraph={authorParagraph}
                x={8}
                y={itemWidth + (labelHeight - 10) / 3}
                width={60}
              />
            )}

            {likeParagraph && (
              <Paragraph
                paragraph={likeParagraph}
                x={itemWidth - 32}
                y={itemWidth + (labelHeight - 10) / 3}
                width={40}
              />
            )}
          </Group>

          {/* 先画阴影，再画描边，保证描边永远在最外层 */}
          <ParallelogramShadow
            height={cardHeight + shadowMargin}
            baseHeight={cardHeight}
            padding={padding}
            skewOffset={skewOffset}
            width={itemWidth}
          />

          <Path
            path={parallelogramPath}
            style="stroke"
            strokeWidth={3}
            color={isSelected ? '#FFE500' : '#323232'}
          />
        </Canvas>
      </Block>
    </Pressable>
  )
})

export default ParallelogramGridItem