import React from 'react'; import { StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native'; import { View, Text, useTheme } from '@bettoredge/styles'; import { Ionicons } from '@expo/vector-icons'; import type { CalcuttaCompetitionProps } from '@bettoredge/types'; import type { CalcuttaLifecycleState } from '../helpers/lifecycleState'; import { formatCurrency } from '../helpers/formatting'; import { CalcuttaCountdown } from './CalcuttaCountdown'; export interface CalcuttaActionCardProps { competition: CalcuttaCompetitionProps; lifecycleState: CalcuttaLifecycleState; hasJoined: boolean; escrowBalance?: number; activeBidCount?: number; itemsWon?: number; isAdmin?: boolean; participantCount?: number; onJoin?: () => void; onDepositEscrow?: () => void; onManage?: () => void; onStartAuction?: () => void; joining?: boolean; } interface CardConfig { icon: string; title: string; description: string; accentColor: string; ctaLabel?: string; ctaColor?: string; ctaAction?: () => void; secondaryCtaLabel?: string; secondaryCtaColor?: string; secondaryCtaAction?: () => void; showCountdown?: 'start' | 'end'; loading?: boolean; secondaryLoading?: boolean; } export const CalcuttaActionCard: React.FC = ({ competition, lifecycleState, hasJoined, escrowBalance = 0, activeBidCount = 0, itemsWon = 0, isAdmin, participantCount = 0, onJoin, onDepositEscrow, onManage, onStartAuction, joining, }) => { const { theme } = useTheme(); const isSweepstakes = competition.auction_type === 'sweepstakes'; const entryFee = Number(competition.entry_fee) || 0; const isFree = entryFee === 0; const getConfig = (): CardConfig => { // Admin: can start auction if (isAdmin && lifecycleState === 'scheduled' && onStartAuction) { const config: CardConfig = { icon: 'play-circle-outline', title: 'Ready to start?', description: `${participantCount} player${participantCount !== 1 ? 's' : ''} have joined. Start the ${isSweepstakes ? 'competition' : 'auction'} when ready.`, accentColor: theme.colors.primary.default, ctaLabel: isSweepstakes ? 'Start Competition' : 'Start Auction', ctaColor: theme.colors.primary.default, ctaAction: onStartAuction, showCountdown: 'start', }; // Admin hasn't joined yet — show join as secondary action if (!hasJoined && onJoin) { config.secondaryCtaLabel = isFree ? 'Join Free' : `Join — ${formatCurrency(entryFee, competition.market_type)}`; config.secondaryCtaColor = '#10B981'; config.secondaryCtaAction = onJoin; config.secondaryLoading = joining; } return config; } // Not joined — prompt to join if (!hasJoined && (lifecycleState === 'scheduled' || (lifecycleState === 'auctioning' && !isSweepstakes))) { return { icon: 'enter-outline', title: isSweepstakes ? 'Join for a random team!' : 'Join this auction', description: isFree ? 'Free to enter' : `Entry fee: ${formatCurrency(entryFee, competition.market_type)}`, accentColor: '#10B981', ctaLabel: isFree ? 'Join Free' : `Join — ${formatCurrency(entryFee, competition.market_type)}`, ctaColor: '#10B981', ctaAction: onJoin, showCountdown: 'start', loading: joining, }; } // Joined + scheduled if (hasJoined && lifecycleState === 'scheduled') { // Sweepstakes — just waiting if (isSweepstakes) { return { icon: 'checkmark-circle', title: "You're in!", description: 'Your team will be assigned when the host starts the competition.', accentColor: '#10B981', showCountdown: 'start', }; } // No escrow — prompt to fund if (escrowBalance <= 0) { return { icon: 'wallet-outline', title: 'Fund your escrow', description: 'You need funds in your escrow to place bids when the auction opens.', accentColor: '#D97706', ctaLabel: 'Add Funds', ctaColor: '#D97706', ctaAction: onDepositEscrow, showCountdown: 'start', }; } // Has escrow — ready return { icon: 'checkmark-circle', title: "You're ready!", description: `Escrow: ${formatCurrency(escrowBalance, competition.market_type)} available`, accentColor: '#10B981', showCountdown: 'start', }; } // Auction active if (lifecycleState === 'auctioning' && hasJoined) { if (activeBidCount > 0) { return { icon: 'trophy-outline', title: `You have ${activeBidCount} active bid${activeBidCount !== 1 ? 's' : ''}`, description: competition.auction_type === 'sealed_bid' ? 'Bids are sealed — results revealed when auction closes.' : 'Keep watching for outbid notifications.', accentColor: '#D97706', showCountdown: competition.auction_type === 'sealed_bid' ? 'end' : undefined, }; } return { icon: 'flash-outline', title: 'Auction is live!', description: 'Start placing your bids now.', accentColor: '#D97706', showCountdown: competition.auction_type === 'sealed_bid' ? 'end' : undefined, }; } // Tournament in progress if (lifecycleState === 'tournament') { return { icon: 'football-outline', title: 'Tournament in progress', description: itemsWon > 0 ? `You own ${itemsWon} item${itemsWon !== 1 ? 's' : ''} — track results below.` : 'Follow the action below.', accentColor: '#8B5CF6', }; } // Completed if (lifecycleState === 'completed') { return { icon: 'ribbon-outline', title: 'Competition complete', description: itemsWon > 0 ? `You owned ${itemsWon} item${itemsWon !== 1 ? 's' : ''}.` : 'This competition has ended.', accentColor: theme.colors.text.tertiary, }; } // Admin manage fallback if (isAdmin && onManage) { return { icon: 'settings-outline', title: 'Manage Competition', description: 'Configure settings, items, and payouts.', accentColor: theme.colors.primary.default, ctaLabel: 'Manage', ctaColor: theme.colors.primary.default, ctaAction: onManage, }; } // Default return { icon: 'information-circle-outline', title: competition.competition_name, description: 'Competition details', accentColor: theme.colors.text.tertiary, }; }; const config = getConfig(); return ( {/* Left accent strip */} {/* Icon + Text */} {config.title} {config.description} {/* Countdown */} {config.showCountdown === 'start' && competition.scheduled_datetime && ( )} {config.showCountdown === 'end' && competition.auction_end_datetime && ( )} {/* Secondary CTA Button */} {config.secondaryCtaLabel && config.secondaryCtaAction && ( {config.secondaryLoading ? ( ) : ( {config.secondaryCtaLabel} )} )} {/* CTA Button */} {config.ctaLabel && config.ctaAction && ( {config.loading ? ( ) : ( {config.ctaLabel} )} )} ); }; const styles = StyleSheet.create({ card: { borderRadius: 16, borderWidth: 1, flexDirection: 'row', overflow: 'hidden', }, accent: { width: 4, }, content: { flex: 1, padding: 16, }, topRow: { flexDirection: 'row', alignItems: 'flex-start', }, iconCircle: { width: 42, height: 42, borderRadius: 21, alignItems: 'center', justifyContent: 'center', }, textBlock: { flex: 1, marginLeft: 12, justifyContent: 'center', }, countdownRow: { marginTop: 10, }, ctaButton: { marginTop: 14, height: 44, borderRadius: 10, alignItems: 'center', justifyContent: 'center', }, });