import { View, Text, StyleSheet, FlatList, TouchableOpacity, ActivityIndicator, Modal, Pressable, Platform } from "react-native"; import { useLocalSearchParams, useRouter } from "expo-router"; import { useEffect, useState } from "react"; import { LinearGradient } from "expo-linear-gradient"; import { BlurView } from "expo-blur"; import { supabase } from "../../src/lib/supabase"; import { usePacksStore, useSubscriptionStore, useAuthStore } from "../../src/store"; import { Ionicons } from "@expo/vector-icons"; import Animated, { FadeInDown, useSharedValue, useAnimatedScrollHandler, useAnimatedStyle, interpolate, Extrapolation, } from "react-native-reanimated"; import { GradientBackground, GlassCard } from "../../src/components/ui"; import { colors, gradients, spacing, radius, typography } from "../../src/theme"; import { getPackIconName } from "../../src/lib/packIcons"; import { Question } from "../../src/types"; type TooltipType = 'initiator' | 'coupleType' | null; const TOOLTIP_CONTENT = { initiator: { title: 'Initiator Filter', description: 'The "initiator" is the first person in the couple to see and answer this question. This icon shows which genders can be the initiator. Their partner will always see the question afterward, regardless of this setting.', }, coupleType: { title: 'Couple Type Filter', description: 'This shows which couple compositions can see this question. For example, a male+female icon means the question is only shown to couples where one partner is male and one is female.', }, }; const ACCENT_COLOR = colors.primary; const NAV_BAR_HEIGHT = 44; const STATUS_BAR_HEIGHT = 60; const HERO_HEIGHT = 260; const HEADER_SCROLL_DISTANCE = 120; const AnimatedFlatList = Animated.createAnimatedComponent(FlatList); export default function PackDetailsScreen() { const { id } = useLocalSearchParams(); const router = useRouter(); const { packs, fetchPacks } = usePacksStore(); const { subscription } = useSubscriptionStore(); const { user, partner } = useAuthStore(); const [questions, setQuestions] = useState([]); const [isLoading, setIsLoading] = useState(true); const [activeTooltip, setActiveTooltip] = useState(null); const scrollY = useSharedValue(0); const pack = packs.find((p) => p.id === id); const hasPremiumAccess = user?.is_premium || partner?.is_premium || subscription.isProUser; const isPremium = pack?.is_premium && hasPremiumAccess; const { categories } = usePacksStore(); const category = categories.find(c => c.id === pack?.category_id); useEffect(() => { if (packs.length === 0) { fetchPacks(); } fetchPackDetails(); }, [id]); const fetchPackDetails = async () => { try { const { data, error } = await supabase .from("questions") .select("id, pack_id, text, partner_text, intensity, allowed_couple_genders, target_user_genders, created_at") .eq("pack_id", id) .order("created_at"); if (error) throw error; setQuestions(data || []); } catch (error) { console.error("Error fetching questions:", error); } finally { setIsLoading(false); } }; const scrollHandler = useAnimatedScrollHandler({ onScroll: (event) => { scrollY.value = event.contentOffset.y; }, }); // Animated styles for collapsing header const heroStyle = useAnimatedStyle(() => { const opacity = interpolate( scrollY.value, [0, HEADER_SCROLL_DISTANCE * 0.7], [1, 0], Extrapolation.CLAMP ); const scale = interpolate( scrollY.value, [0, HEADER_SCROLL_DISTANCE], [1, 0.95], Extrapolation.CLAMP ); return { opacity, transform: [{ scale }] }; }); const compactHeaderStyle = useAnimatedStyle(() => { const opacity = interpolate( scrollY.value, [HEADER_SCROLL_DISTANCE * 0.5, HEADER_SCROLL_DISTANCE], [0, 1], Extrapolation.CLAMP ); return { opacity }; }); const navBarBackgroundStyle = useAnimatedStyle(() => { const opacity = interpolate( scrollY.value, [0, HEADER_SCROLL_DISTANCE * 0.8], [0, 1], Extrapolation.CLAMP ); return { opacity }; }); const useBlur = Platform.OS === 'ios'; const renderItem = ({ item, index }: { item: Question; index: number }) => { return ( #{index + 1} {item.text} {item.partner_text && ( {item.partner_text} )} {[...Array(5)].map((_, i) => ( ))} {item.target_user_genders && item.target_user_genders.length > 0 && ( setActiveTooltip('initiator')} > {item.target_user_genders.map((g, i) => ( 0 ? { marginLeft: 2 } : {}} /> ))} )} setActiveTooltip('coupleType')} > {item.allowed_couple_genders && item.allowed_couple_genders.length > 0 ? ( item.allowed_couple_genders.map((g) => { const icons: ('male' | 'female')[] = []; if (g === 'male+male') { icons.push('male', 'male'); } else if (g === 'female+female') { icons.push('female', 'female'); } else { icons.push('male', 'female'); } return ( {icons.map((icon, i) => ( 0 ? { marginLeft: 2 } : {}} /> ))} ); }) ) : ( )} ); }; const heroContent = ( {/* Premium Banner */} {pack?.is_premium && ( PREMIUM COLLECTION )} {/* Category label */} {category ? category.name.toUpperCase() : 'PREVIEW'} {/* Explicit badge */} {pack?.is_explicit && ( 18+ EXPLICIT )} {/* Icon with enhanced glow for premium */} {pack?.is_premium && ( <> {/* Glow effects removed for flat design */} )} {pack?.is_premium && ( )} {/* Crown for premium */} {pack?.is_premium && ( )} {/* Title */} {pack?.name || "Pack Details"} {/* Premium badge - larger and more prominent */} {pack?.is_premium && ( PREMIUM )} {/* Decorative separator */} {/* Description */} {pack?.description} {/* Stats badge */} {questions.length} questions ); if (isLoading) { return ( ); } return ( {/* Fixed Nav Bar */} router.back()} style={styles.backButton}> {pack?.name || "Pack Details"} {/* Questions List with Hero Header */} item.id} showsVerticalScrollIndicator={false} onScroll={scrollHandler} scrollEventThrottle={16} contentContainerStyle={styles.list} ListHeaderComponent={ {heroContent} } ListEmptyComponent={ No questions in this pack yet } /> {/* Tooltip Modal */} setActiveTooltip(null)} > setActiveTooltip(null)} > {activeTooltip && TOOLTIP_CONTENT[activeTooltip].title} {activeTooltip && TOOLTIP_CONTENT[activeTooltip].description} setActiveTooltip(null)} > Got it ); } const styles = StyleSheet.create({ container: { flex: 1, }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", }, // Fixed Nav Bar navBar: { position: "absolute", top: 0, left: 0, right: 0, height: STATUS_BAR_HEIGHT + NAV_BAR_HEIGHT, flexDirection: "row", alignItems: "center", paddingTop: STATUS_BAR_HEIGHT - 10, paddingHorizontal: spacing.md, zIndex: 100, }, navBarBackground: { ...StyleSheet.absoluteFillObject, borderBottomWidth: 1, borderBottomColor: colors.border, overflow: "hidden", backgroundColor: colors.background, // Flat }, // ... // ... premiumBanner: { marginHorizontal: spacing.lg, marginBottom: spacing.lg, borderRadius: radius.md, overflow: 'hidden', // Removed heavy shadow borderWidth: 1, borderColor: colors.premium.gold, }, // ... iconWrapper: { position: 'relative', marginBottom: spacing.md, // Removed glowing background elements }, // ... iconContainer: { width: 72, height: 72, borderRadius: 36, backgroundColor: colors.backgroundLight, justifyContent: 'center', alignItems: 'center', borderWidth: 1, borderColor: colors.border, overflow: 'hidden', }, iconContainerPremium: { borderColor: colors.premium.gold, borderWidth: 2, backgroundColor: colors.backgroundLight, // Removed heavy shadows }, // ... statsBadge: { flexDirection: 'row', alignItems: 'center', gap: spacing.xs, backgroundColor: colors.backgroundLight, paddingHorizontal: spacing.lg, paddingVertical: spacing.sm, borderRadius: radius.full, borderWidth: 1, borderColor: colors.border, }, // ... questionCard: { backgroundColor: colors.backgroundLight, // Flat borderRadius: radius.md, borderWidth: 1, borderColor: colors.border, marginBottom: spacing.sm, }, // ... partnerTextContainer: { flexDirection: 'row', alignItems: 'center', gap: spacing.xs, marginBottom: spacing.sm, paddingVertical: spacing.xs, paddingHorizontal: spacing.sm, backgroundColor: colors.background, // Nested flat container borderRadius: radius.sm, alignSelf: 'flex-start', borderWidth: 1, borderColor: colors.border, }, // ... tooltipContainer: { maxWidth: 320, overflow: 'hidden', backgroundColor: colors.backgroundLight, // Flat borderWidth: 1, borderColor: colors.border, }, backButton: { zIndex: 10, }, backButtonInner: { width: 36, height: 36, borderRadius: 18, backgroundColor: 'rgba(255, 255, 255, 0.08)', justifyContent: 'center', alignItems: 'center', borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.1)', }, navBarTitle: { flex: 1, ...typography.headline, color: colors.text, textAlign: "center", marginRight: 36, }, navBarSpacer: { width: 0, }, // Hero Section heroContainer: { marginBottom: spacing.lg, }, heroInner: { paddingTop: STATUS_BAR_HEIGHT + spacing.md, paddingBottom: spacing.lg, minHeight: HERO_HEIGHT, }, heroContent: { alignItems: 'center', paddingHorizontal: spacing.lg, }, // Premium Banner premiumBannerContent: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: spacing.sm, paddingHorizontal: spacing.md, gap: spacing.sm, }, premiumBannerText: { ...typography.caption1, fontWeight: '800', letterSpacing: 2, color: colors.background, }, label: { ...typography.caption1, fontWeight: '600', letterSpacing: 3, color: ACCENT_COLOR, textAlign: 'center', marginBottom: spacing.md, }, labelPremium: { color: colors.premium.gold, }, explicitBadge: { flexDirection: 'row', alignItems: 'center', backgroundColor: colors.error, paddingHorizontal: spacing.md, paddingVertical: spacing.xs, borderRadius: radius.full, gap: spacing.xs, marginBottom: spacing.md, }, explicitBadgeText: { ...typography.caption2, fontWeight: '700', color: colors.text, letterSpacing: 1, }, // Removed glow styles iconGlowOuter: { display: 'none', }, iconGlow: { display: 'none', }, crownBadge: { position: 'absolute', top: -4, right: -4, width: 24, height: 24, borderRadius: 12, backgroundColor: colors.background, justifyContent: 'center', alignItems: 'center', borderWidth: 2, borderColor: colors.premium.gold, shadowColor: colors.premium.gold, shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.4, shadowRadius: 4, elevation: 4, }, title: { ...typography.largeTitle, color: colors.text, textAlign: 'center', marginBottom: spacing.sm, }, titlePremium: { textShadowColor: 'rgba(212, 175, 55, 0.3)', textShadowOffset: { width: 0, height: 0 }, textShadowRadius: 10, }, proBadge: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: spacing.md, paddingVertical: spacing.xs, borderRadius: radius.full, gap: spacing.xs, marginBottom: spacing.sm, overflow: 'hidden', shadowColor: colors.premium.gold, shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.4, shadowRadius: 6, elevation: 6, }, proBadgeText: { ...typography.caption1, color: colors.background, fontWeight: '800', letterSpacing: 1.5, }, separator: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', marginVertical: spacing.md, width: 140, }, separatorLine: { flex: 1, height: 1, backgroundColor: 'rgba(233, 69, 96, 0.25)', }, separatorLinePremium: { backgroundColor: 'rgba(212, 175, 55, 0.4)', }, separatorDiamond: { width: 6, height: 6, backgroundColor: ACCENT_COLOR, transform: [{ rotate: '45deg' }], marginHorizontal: spacing.md, opacity: 0.6, }, separatorDiamondPremium: { backgroundColor: colors.premium.gold, opacity: 1, }, description: { ...typography.body, color: colors.textSecondary, textAlign: 'center', lineHeight: 24, paddingHorizontal: spacing.md, marginBottom: spacing.md, }, statsBadgePremium: { backgroundColor: 'rgba(212, 175, 55, 0.1)', borderColor: 'rgba(212, 175, 55, 0.3)', }, statsText: { ...typography.subhead, color: colors.textSecondary, fontWeight: '500', }, statsTextPremium: { color: colors.premium.champagne, }, // List list: { paddingHorizontal: spacing.md, paddingBottom: Platform.OS === 'ios' ? 100 : 80, }, questionContent: { padding: spacing.md, }, questionNumber: { ...typography.caption2, color: colors.textTertiary, marginBottom: spacing.xs, }, questionText: { ...typography.body, color: colors.text, marginBottom: spacing.sm, lineHeight: 22, }, partnerText: { ...typography.caption1, color: colors.premium.rose, fontStyle: 'italic', }, footerContainer: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginTop: spacing.xs, paddingTop: spacing.xs, borderTopWidth: 1, borderTopColor: 'rgba(255, 255, 255, 0.04)', }, intensityContainer: { flexDirection: 'row', }, badgesContainer: { flexDirection: 'row', gap: spacing.xs, }, targetBadge: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: spacing.xs, paddingVertical: 2, }, coupleIconGroup: { flexDirection: 'row', alignItems: 'center', }, emptyContainer: { alignItems: 'center', paddingVertical: spacing.xxl, gap: spacing.md, }, emptyText: { ...typography.body, color: colors.textSecondary, }, modalOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.7)', justifyContent: 'center', alignItems: 'center', padding: spacing.lg, }, tooltipTitle: { ...typography.title3, color: colors.text, marginBottom: spacing.sm, }, tooltipDescription: { ...typography.body, color: colors.textSecondary, lineHeight: 24, marginBottom: spacing.lg, }, tooltipButton: { borderRadius: radius.md, overflow: 'hidden', }, tooltipButtonGradient: { paddingVertical: spacing.sm, alignItems: 'center', }, tooltipButtonText: { ...typography.headline, color: colors.text, }, });