import React, { memo, useCallback, useMemo } from 'react'
import { Pressable, StyleSheet, Text, View, ViewStyle } from 'react-native'
import { Image } from 'expo-image'
import { LinearGradient } from 'expo-linear-gradient'

export interface TemplateCardProps {
  id?: string
  title: string
  previewUrl?: string
  webpPreviewUrl?: string
  coverImageUrl?: string
  aspectRatio?: string
  cardWidth: number
  onPress: (id: string) => void
  testID?: string
}

/**
 * 解析 aspectRatio 字符串为数字
 * 例如: "128:128" -> 1, "16:9" -> 1.777..., "1.5" -> 1.5
 */
export function parseAspectRatio(aspectRatioString?: string): number | undefined {
  if (!aspectRatioString) return undefined

  if (aspectRatioString.includes(':')) {
    const [w, h] = aspectRatioString.split(':').map(Number)
    return w / h
  }

  return Number(aspectRatioString)
}

/**
 * 获取图片源 URI，按优先级: webpPreviewUrl > previewUrl > coverImageUrl
 */
export function getImageUri(
  webpPreviewUrl?: string,
  previewUrl?: string,
  coverImageUrl?: string
): string | undefined {
  return webpPreviewUrl || previewUrl || coverImageUrl
}

// 渐变颜色常量，避免每次渲染创建新数组
const GRADIENT_COLORS = ['rgba(17, 17, 17, 0)', 'rgba(17, 17, 17, 0.9)'] as const
const GRADIENT_START = { x: 0, y: 0 }
const GRADIENT_END = { x: 0, y: 1 }

const TemplateCardComponent: React.FC<TemplateCardProps> = ({
  id,
  title,
  previewUrl,
  webpPreviewUrl,
  coverImageUrl,
  aspectRatio: aspectRatioString,
  cardWidth,
  onPress,
  testID,
}) => {
  const aspectRatio = useMemo(() => parseAspectRatio(aspectRatioString), [aspectRatioString])
  const imageUri = useMemo(() => getImageUri(webpPreviewUrl, previewUrl, coverImageUrl), [webpPreviewUrl, previewUrl, coverImageUrl])

  // 使用 useCallback 缓存 onPress 回调
  const handlePress = useCallback(() => {
    if (id) {
      onPress(id)
    }
  }, [id, onPress])

  // 缓存样式计算
  const cardStyle = useMemo(() => [styles.card, { width: cardWidth }], [cardWidth])
  const containerStyle = useMemo(() =>
    [styles.cardImageContainer, aspectRatio ? { aspectRatio } : undefined].filter(Boolean) as ViewStyle[],
    [aspectRatio]
  )
  const imageStyle = useMemo(() =>
    [styles.cardImage, aspectRatio ? { aspectRatio } : undefined].filter(Boolean) as ViewStyle[],
    [aspectRatio]
  )

  // 如果没有 id，则不渲染卡片
  if (!id) {
    return null
  }

  return (
    <Pressable
      style={cardStyle}
      onPress={handlePress}
      testID={testID}
    >
      <View style={containerStyle}>
        <Image
          source={{ uri: imageUri }}
          style={imageStyle}
          contentFit="cover"
          cachePolicy="memory-disk"
          recyclingKey={id}
          transition={200}
        />
        <LinearGradient
          colors={GRADIENT_COLORS}
          start={GRADIENT_START}
          end={GRADIENT_END}
          style={styles.cardImageGradient}
        />
        <Text style={styles.cardTitle} numberOfLines={1}>
          {title}
        </Text>
      </View>
    </Pressable>
  )
}

export const TemplateCard = memo(TemplateCardComponent)

const styles = StyleSheet.create({
  card: {
    marginBottom: 5,
  },
  cardImageContainer: {
    width: '100%',
    borderRadius: 8,
    overflow: 'hidden',
    position: 'relative',
  },
  cardImage: {
    width: '100%',
    borderRadius: 8,
  },
  cardImageGradient: {
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
    height: '50%',
  },
  cardTitle: {
    position: 'absolute',
    bottom: 8,
    left: 8,
    right: 8,
    color: '#F5F5F5',
    fontSize: 12,
    fontWeight: '500',
  },
})
