import { LEVEL_MAP } from '@/constants/config'; import { Images } from '@/constants/images'; import { Image, ImageBackground } from 'expo-image'; import React, { useMemo } from 'react'; import { Dimensions, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; const { width } = Dimensions.get('window'); interface ProductListYfsProps { products: any[]; poolId: string; box: any; onProductClick?: (product: any) => void; } export default function ProductListYfs({ products = [], poolId, box, onProductClick }: ProductListYfsProps) { const levels = useMemo(() => { console.log('ProductListYfs products:', products ? products.length : 'null'); const grouped: Record = { A: [], B: [], C: [], D: [] }; products.forEach(p => { console.log('Processing item level:', p.level); if (grouped[p.level]) { grouped[p.level].push(p); } else { console.log('Unknown level:', p.level); } }); const result = [ { level: 'A', list: grouped.A, ...LEVEL_MAP.A }, { level: 'B', list: grouped.B, ...LEVEL_MAP.B }, { level: 'C', list: grouped.C, ...LEVEL_MAP.C }, { level: 'D', list: grouped.D, ...LEVEL_MAP.D }, ].filter(g => g.list && g.list.length > 0); console.log('ProductListYfs levels:', result.length); return result; }, [products]); const getLeftNum = (item: any) => { if (!box || !box.usedStat || !box.usedStat[item.spu.id]) { return item.quantity; } return item.quantity - (box.usedStat[item.spu.id].quantity || 0); }; const getProbability = (item: any) => { if (!box || !box.leftQuantity) return '0%'; const left = getLeftNum(item); const prob = (left / box.leftQuantity * 100).toFixed(4); return parseFloat(prob) === 0 ? '0%' : `${prob}%`; }; const getLevelProbability = (level: string) => { if (!box || !box.leftQuantity) return '0%'; let sumLeft = 0; products.filter(p => p.level === level).forEach(p => { sumLeft += getLeftNum(p); }); const prob = (sumLeft / box.leftQuantity * 100).toFixed(4); return parseFloat(prob) === 0 ? '0%' : `${prob}%`; }; if (!products || products.length === 0) return null; return ( {levels.map((levelItem) => ( {/* Header with Title and Probability */} {levelItem.title} {getLevelProbability(levelItem.level)} {/* The legacy code used borders and backgrounds for titles, but for now text color + shadow mimics the look well enough or we can add ImageBackground if needed. Legacy: :style="{ color: LEVEL_MAP[levelItem.level].color }" and centered. */} {/* List Container - Legacy uses levelBoxBg for EACH item container? Legacy: ... */} {levelItem.list.map((item, index) => ( onProductClick && onProductClick(item)} > {/* Item Background (levelBoxBg) */} {/* Info Box (productItemA/B/C/D) */} 概率: {getProbability(item)} {getLeftNum(item)}/{item.quantity} ))} ))} ); } const styles = StyleSheet.create({ container: { paddingHorizontal: 10, paddingVertical: 10, }, levelGroup: { marginBottom: 5, }, levelHeader: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', marginBottom: 5, position: 'relative', height: 40, }, levelTitle: { fontSize: 18, fontWeight: 'bold', textShadowColor: '#000', textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 1, }, levelProb: { position: 'absolute', right: 15, bottom: 5, color: '#fff', fontSize: 12, fontFamily: 'System', // Prevent potential font missing issues }, listWrapper: { paddingBottom: 10, }, scrollContent: { paddingRight: 10, }, itemContainer: { width: 88, // 175rpx / 2 height: 110, // 220rpx / 2 marginRight: 8, }, itemBg: { width: '100%', height: '100%', position: 'relative', }, itemImage: { width: 88, height: 90, position: 'absolute', top: 0, left: 0, zIndex: 1, }, textBox: { width: '100%', height: 53, // 106rpx / 2 position: 'absolute', bottom: 0, // Adjusted from top: -30rpx legacy logic which was weird, simplified for RN zIndex: 2, justifyContent: 'flex-start', paddingTop: 18, // Push content down below the curve alignItems: 'center', }, probTag: { flexDirection: 'row', alignItems: 'center', }, probLabel: { fontSize: 8, marginRight: 2, }, probValue: { fontSize: 8, fontWeight: 'bold', color: '#333' }, countTag: { position: 'absolute', top: 0, right: 0, paddingHorizontal: 4, borderRadius: 2, zIndex: 3, }, countText: { color: '#fff', fontSize: 9, } });