import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { StyleSheet, ActivityIndicator, TouchableOpacity, ScrollView, Platform, useWindowDimensions } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { View, Text, useTheme, toast } from '@bettoredge/styles';
import { useCalcuttaAuction } from '../../hooks/useCalcuttaAuction';
import { useCalcuttaEscrow } from '../../hooks/useCalcuttaEscrow';
import { useCalcuttaBid } from '../../hooks/useCalcuttaBid';
import { useCalcuttaSocket } from '../../hooks/useCalcuttaSocket';
import { useCalcuttaCompetition } from '../../hooks/useCalcuttaCompetition';
import { useCalcuttaPlayers } from '../../hooks/useCalcuttaPlayers';
import { useCalcuttaItemImages } from '../../hooks/useCalcuttaItemImages';
import { deriveLifecycleState, canBid as canBidCheck, type CalcuttaLifecycleState } from '../../helpers/lifecycleState';
import { formatCurrency } from '../../helpers/formatting';
import { SealedBidHeader } from './SealedBidHeader';
import { SealedBidStatusBar } from './SealedBidStatusBar';
import { SealedBidTabBar, SealedBidTab } from './SealedBidTabBar';
import { SealedBidItemsTab } from './SealedBidItemsTab';
import { SealedBidMyBidsTab } from './SealedBidMyBidsTab';
import { SealedBidPlayersTab } from './SealedBidPlayersTab';
import { SealedBidInfoTab } from './SealedBidInfoTab';
import { EscrowBottomSheet } from './EscrowBottomSheet';
import { AuctionResultsModal } from './AuctionResultsModal';
import { CalcuttaRoundResults } from '../CalcuttaRoundResults';
import { CalcuttaLeaderboard } from '../CalcuttaLeaderboard';

interface SealedBidAuctionProps {
    calcutta_competition_id: string;
    player_id?: string;
    onClose?: () => void;
    access_token?: string;
    device_id?: string;
    getSocket?: () => WebSocket | null;
    getAccessToken?: () => string | undefined;
    getDeviceId?: () => string | undefined;
    player_data?: { username: string; profile_pic?: string };
    player_balance?: number;
    onDepositFunds?: (amount: number) => void;
    onManage?: () => void;
    onJoin?: () => void | Promise<void>;
    onLeave?: () => void | Promise<void>;
}

/** Poll interval per lifecycle state */
function getPollInterval(state: CalcuttaLifecycleState, auctionExpired: boolean): number {
    // When timer expired but server hasn't confirmed close, poll aggressively
    if (auctionExpired && state === 'auctioning') return 3000;
    switch (state) {
        case 'auctioning': return 10000;
        case 'tournament': return 60000;
        default: return 0;
    }
}

export const SealedBidAuction: React.FC<SealedBidAuctionProps> = ({
    calcutta_competition_id,
    player_id,
    onClose,
    access_token,
    device_id,
    player_data,
    player_balance,
    onDepositFunds,
    onManage,
    onJoin,
    onLeave,
}) => {
    const { theme } = useTheme();
    const { width: windowWidth } = useWindowDimensions();
    const [containerWidth, setContainerWidth] = useState(0);
    const measuredWidth = containerWidth || windowWidth;
    const isDesktop = Platform.OS === 'web' && measuredWidth >= 700;
    const [activeTab, setActiveTab] = useState<SealedBidTab>('items');
    const [escrowSheetVisible, setEscrowSheetVisible] = useState(false);
    const [refreshing, setRefreshing] = useState(false);
    const [showResultsModal, setShowResultsModal] = useState(false);

    // Client-side flag: auction end time has passed.
    // Does NOT change lifecycle state — only disables bid actions.
    // Lifecycle only changes when the SERVER confirms auction_status='closed'.
    const [auctionExpired, setAuctionExpired] = useState(false);

    // Track previous lifecycle state to detect transitions
    const prevLifecycleRef = useRef<CalcuttaLifecycleState | undefined>(undefined);
    const hasShownResultsRef = useRef(false);

    // Competition detail (rounds, participants, payout rules, item_results)
    const {
        rounds,
        participants,
        payout_rules,
        item_results,
        refresh: refreshCompetition,
    } = useCalcuttaCompetition(calcutta_competition_id);

    // Auction data (items, bids)
    const {
        loading,
        competition,
        items,
        my_bids,
        refresh: refreshAuction,
    } = useCalcuttaAuction(calcutta_competition_id, 10000, player_id);

    // Client-side check: has the auction end time passed?
    useEffect(() => {
        if (!competition?.auction_end_datetime) return;
        const end = new Date(competition.auction_end_datetime).getTime();
        const now = Date.now();

        if (now >= end) {
            setAuctionExpired(true);
            return;
        }

        // Set a timer to flip the flag the instant the deadline passes
        const delay = end - now;
        const timer = setTimeout(() => {
            setAuctionExpired(true);
            // Immediately poll the server for fresh status
            refreshAuction();
            refreshCompetition();
        }, delay);

        return () => clearTimeout(timer);
    }, [competition?.auction_end_datetime, refreshAuction, refreshCompetition]);

    // Derive lifecycle state — only from server data, no client override
    const lifecycleState = deriveLifecycleState(
        competition?.status,
        competition?.auction_status,
    );

    // Bidding is disabled when lifecycle says no OR when the timer has expired
    const biddingDisabled = !canBidCheck(lifecycleState) || auctionExpired;

    // Escrow
    const { escrow, fetchEscrow } = useCalcuttaEscrow(calcutta_competition_id);

    // Bid actions
    const { placeBid, cancelBid, loading: bidLoading } = useCalcuttaBid();

    // Player enrichment
    const participantIds = useMemo(
        () => participants.map(p => p.player_id),
        [participants],
    );
    const { players } = useCalcuttaPlayers(participantIds);

    // Item images (team logos / athlete photos)
    const { images: itemImages } = useCalcuttaItemImages(items);

    // Socket for presence
    const { connected: socketConnected, presence } = useCalcuttaSocket(
        calcutta_competition_id,
        access_token,
        device_id,
        player_data || { username: '' },
    );

    // Adaptive polling based on lifecycle state
    const pollInterval = getPollInterval(lifecycleState, auctionExpired);
    useEffect(() => {
        if (pollInterval <= 0) return;
        const id = setInterval(() => {
            refreshAuction();
            refreshCompetition();
        }, pollInterval);
        return () => clearInterval(id);
    }, [pollInterval, refreshAuction, refreshCompetition]);

    // Detect auctioning → tournament transition → show results modal
    useEffect(() => {
        if (!competition || hasShownResultsRef.current) return;
        const prev = prevLifecycleRef.current;
        const curr = lifecycleState;

        const justTransitioned = prev === 'auctioning' && (curr === 'tournament' || curr === 'completed');

        if (justTransitioned) {
            setShowResultsModal(true);
            hasShownResultsRef.current = true;
        }
        prevLifecycleRef.current = curr;
    }, [lifecycleState, competition]);

    // Auto-switch tab when state changes
    useEffect(() => {
        const prev = prevLifecycleRef.current;
        if (!prev) return;

        if (lifecycleState === 'tournament' || lifecycleState === 'completed') {
            setActiveTab('my_items');
        } else if (lifecycleState === 'auctioning') {
            setActiveTab('items');
        }
    }, [lifecycleState]);

    // On first load, set the correct default tab for the current state
    const hasSetInitialTab = useRef(false);
    useEffect(() => {
        if (hasSetInitialTab.current || !competition) return;
        hasSetInitialTab.current = true;

        if (lifecycleState === 'tournament' || lifecycleState === 'completed') {
            setActiveTab('my_items');
        }
    }, [lifecycleState, competition]);

    useEffect(() => {
        fetchEscrow();
    }, [fetchEscrow]);

    const handlePlaceBid = useCallback(async (calcutta_auction_item_id: string, amount: number) => {
        if (biddingDisabled) return;
        try {
            await placeBid(calcutta_auction_item_id, amount);
            fetchEscrow();
            refreshAuction();
            toast.success('Bid placed');
        } catch (e: any) {
            toast.error(e?.message || 'Failed to place bid');
        }
    }, [placeBid, fetchEscrow, refreshAuction, biddingDisabled]);

    const handleCancelBid = useCallback(async (calcutta_bid_id: string) => {
        if (biddingDisabled) return;
        try {
            await cancelBid(calcutta_bid_id);
            fetchEscrow();
            refreshAuction();
            toast.success('Bid cancelled');
        } catch (e: any) {
            toast.error(e?.message || 'Failed to cancel bid');
        }
    }, [cancelBid, fetchEscrow, refreshAuction, biddingDisabled]);

    const handleUpdateBid = useCallback((calcutta_auction_item_id: string) => {
        if (biddingDisabled) return;
        setActiveTab('items');
    }, [biddingDisabled]);

    const handleRefresh = useCallback(async () => {
        setRefreshing(true);
        await Promise.all([refreshAuction(), refreshCompetition(), fetchEscrow()]);
        setRefreshing(false);
    }, [refreshAuction, refreshCompetition, fetchEscrow]);

    const handleEscrowUpdate = useCallback(() => {
        fetchEscrow();
    }, [fetchEscrow]);

    const handleResultsDismiss = useCallback(() => {
        setShowResultsModal(false);
        setActiveTab('my_items');
    }, []);

    const [joining, setJoining] = useState(false);
    const handleJoin = useCallback(async () => {
        if (!onJoin) return;
        setJoining(true);
        try {
            await onJoin();
            await Promise.all([refreshAuction(), refreshCompetition(), fetchEscrow()]);
            toast.success('Joined auction');
        } catch (e: any) {
            toast.error(e?.message || 'Failed to join auction');
        }
        setJoining(false);
    }, [onJoin, refreshAuction, refreshCompetition, fetchEscrow]);

    const [leaving, setLeaving] = useState(false);
    const handleLeave = useCallback(async () => {
        if (!onLeave) return;
        setLeaving(true);
        try {
            await onLeave();
            await Promise.all([refreshAuction(), refreshCompetition(), fetchEscrow()]);
            toast.success('Left auction');
        } catch (e: any) {
            toast.error(e?.message || 'Failed to leave auction');
        }
        setLeaving(false);
    }, [onLeave, refreshAuction, refreshCompetition, fetchEscrow]);

    if (loading && !competition) {
        return (
            <View variant="transparent" style={styles.loadingContainer}>
                <ActivityIndicator size="large" color={theme.colors.primary.default} />
            </View>
        );
    }

    if (!competition) {
        return (
            <View variant="transparent" style={styles.loadingContainer}>
                <Text variant="body" color="secondary">Auction not found</Text>
            </View>
        );
    }

    const isAdmin = player_id != null && competition.admin_id === player_id;
    const isParticipant = player_id != null && participants.some(p => p.player_id === player_id);

    // All items I purchased at auction (includes active + eliminated)
    const myPurchasedItems = (lifecycleState === 'tournament' || lifecycleState === 'completed')
        ? items.filter(i => i.winning_player_id === player_id)
        : [];
    // Only active (non-eliminated) for the results modal
    const wonItems = myPurchasedItems.filter(i => i.status === 'sold');
    const myBidTabCount = (lifecycleState === 'tournament' || lifecycleState === 'completed')
        ? myPurchasedItems.length
        : my_bids.filter(b => b.bid_status === 'active').length;

    const statusBar = (
        <SealedBidStatusBar
            competition={competition}
            escrow={escrow}
            my_bids={my_bids}
            items={items}
            totalItems={items.length}
            market_type={competition.market_type}
            player_id={player_id}
            lifecycleState={lifecycleState}
            auctionExpired={auctionExpired}
            isParticipant={isParticipant}
            onEscrowTap={() => setEscrowSheetVisible(true)}
            onLeave={isParticipant && onLeave && lifecycleState === 'auctioning' ? handleLeave : undefined}
            leaving={leaving}
        />
    );

    return (
        <View variant="transparent" style={[styles.container, { backgroundColor: theme.colors.surface.base }]} onLayout={e => setContainerWidth(e.nativeEvent.layout.width)}>
            <SealedBidHeader
                competition={competition}
                isAdmin={isAdmin}
                onClose={onClose}
                onManage={isAdmin ? onManage : undefined}
                lifecycleState={lifecycleState}
                auctionExpired={auctionExpired}
            />

            {isDesktop ? (
                /* ═══ DESKTOP: all panels visible ═══ */
                <ScrollView style={{ flex: 1, backgroundColor: theme.colors.surface.base }} contentContainerStyle={{ padding: 12, paddingBottom: 40 }} keyboardShouldPersistTaps="handled">
                    {statusBar}

                    {/* Join banner */}
                    {!isParticipant && onJoin && (
                        <View variant="transparent" style={[styles.joinBanner, { backgroundColor: theme.colors.primary.subtle, borderColor: theme.colors.primary.default + '30', marginBottom: 12 }]}>
                            <View variant="transparent" style={styles.joinInfo}>
                                <Ionicons name="enter-outline" size={20} color={theme.colors.primary.default} />
                                <View variant="transparent" style={{ marginLeft: 10, flex: 1 }}>
                                    <Text variant="body" bold>Join this auction</Text>
                                    <Text variant="caption" color="secondary">
                                        {competition.entry_fee > 0 ? `${formatCurrency(competition.entry_fee, competition.market_type)} entry fee` : 'Free to enter'}
                                    </Text>
                                </View>
                            </View>
                            <TouchableOpacity style={[styles.joinBtn, { backgroundColor: theme.colors.primary.default, opacity: joining ? 0.7 : 1 }]} onPress={handleJoin} disabled={joining} activeOpacity={0.7}>
                                {joining ? <ActivityIndicator size="small" color="#FFFFFF" /> : <Text variant="body" bold style={{ color: '#FFFFFF' }}>Join</Text>}
                            </TouchableOpacity>
                        </View>
                    )}

                    {/* Row 1: Items + My Bids */}
                    <View variant="transparent" style={{ flexDirection: 'row', gap: 12 }}>
                        <View variant="transparent" style={[styles.desktopPanel, { flex: 3, backgroundColor: theme.colors.surface.elevated, borderColor: theme.colors.border.subtle }]}>
                            <SealedBidItemsTab
                                items={items} my_bids={my_bids} min_bid={competition.min_bid} bid_increment={competition.bid_increment}
                                escrow_balance={escrow?.escrow_balance ?? 0} market_type={competition.market_type} player_id={player_id}
                                lifecycleState={lifecycleState} itemImages={itemImages} onPlaceBid={handlePlaceBid} bidLoading={bidLoading}
                                onRefresh={handleRefresh} refreshing={refreshing} disabled={biddingDisabled}
                            />
                        </View>
                        <View variant="transparent" style={[styles.desktopPanel, { flex: 2, backgroundColor: theme.colors.surface.elevated, borderColor: theme.colors.border.subtle }]}>
                            <SealedBidMyBidsTab
                                items={items} my_bids={my_bids} escrow={escrow} market_type={competition.market_type} player_id={player_id}
                                lifecycleState={lifecycleState} itemImages={itemImages} item_results={item_results} rounds={rounds}
                                onCancelBid={handleCancelBid} onUpdateBid={handleUpdateBid} cancelLoading={bidLoading} auctionExpired={auctionExpired}
                            />
                        </View>
                    </View>

                    {/* Row 2: Players + Info */}
                    <View variant="transparent" style={{ flexDirection: 'row', gap: 12, marginTop: 12 }}>
                        <View variant="transparent" style={[styles.desktopPanel, { flex: 1, backgroundColor: theme.colors.surface.elevated, borderColor: theme.colors.border.subtle }]}>
                            <SealedBidPlayersTab
                                participants={participants} players={players} player_id={player_id} presence={presence}
                                socketConnected={socketConnected} market_type={competition.market_type} lifecycleState={lifecycleState}
                            />
                        </View>
                        <View variant="transparent" style={[styles.desktopPanel, { flex: 1, backgroundColor: theme.colors.surface.elevated, borderColor: theme.colors.border.subtle }]}>
                            <SealedBidInfoTab
                                competition={competition} rounds={rounds} payout_rules={payout_rules} escrow={escrow}
                                market_type={competition.market_type} player_balance={player_balance} onDepositFunds={onDepositFunds}
                                onEscrowUpdate={handleEscrowUpdate} lifecycleState={lifecycleState}
                            />
                        </View>
                    </View>
                </ScrollView>
            ) : (
                /* ═══ MOBILE: tab system ═══ */
                <>
                    <SealedBidTabBar
                        activeTab={activeTab}
                        onTabChange={setActiveTab}
                        itemCount={items.length}
                        myBidCount={myBidTabCount}
                        playerCount={participants.length}
                        lifecycleState={lifecycleState}
                    />

                    {!isParticipant && onJoin && (
                        <View variant="transparent" style={[styles.joinBanner, { backgroundColor: theme.colors.primary.subtle, borderColor: theme.colors.primary.default + '30' }]}>
                            <View variant="transparent" style={styles.joinInfo}>
                                <Ionicons name="enter-outline" size={20} color={theme.colors.primary.default} />
                                <View variant="transparent" style={{ marginLeft: 10, flex: 1 }}>
                                    <Text variant="body" bold>Join this auction</Text>
                                    <Text variant="caption" color="secondary">
                                        {competition.entry_fee > 0 ? `${formatCurrency(competition.entry_fee, competition.market_type)} entry fee` : 'Free to enter'}
                                    </Text>
                                </View>
                            </View>
                            <TouchableOpacity style={[styles.joinBtn, { backgroundColor: theme.colors.primary.default, opacity: joining ? 0.7 : 1 }]} onPress={handleJoin} disabled={joining} activeOpacity={0.7}>
                                {joining ? <ActivityIndicator size="small" color="#FFFFFF" /> : <Text variant="body" bold style={{ color: '#FFFFFF' }}>Join</Text>}
                            </TouchableOpacity>
                        </View>
                    )}

                    <View variant="transparent" style={styles.tabContent}>
                        {activeTab === 'items' && (
                            <SealedBidItemsTab items={items} my_bids={my_bids} min_bid={competition.min_bid} bid_increment={competition.bid_increment}
                                escrow_balance={escrow?.escrow_balance ?? 0} market_type={competition.market_type} player_id={player_id}
                                lifecycleState={lifecycleState} itemImages={itemImages} onPlaceBid={handlePlaceBid} bidLoading={bidLoading}
                                onRefresh={handleRefresh} refreshing={refreshing} disabled={biddingDisabled} listHeader={statusBar} />
                        )}
                        {activeTab === 'my_bids' && (
                            <SealedBidMyBidsTab items={items} my_bids={my_bids} escrow={escrow} market_type={competition.market_type}
                                player_id={player_id} lifecycleState={lifecycleState} itemImages={itemImages} item_results={item_results}
                                rounds={rounds} onCancelBid={handleCancelBid} onUpdateBid={handleUpdateBid} cancelLoading={bidLoading}
                                auctionExpired={auctionExpired} listHeader={statusBar} />
                        )}
                        {activeTab === 'my_items' && (
                            <SealedBidMyBidsTab items={items} my_bids={my_bids} escrow={escrow} market_type={competition.market_type}
                                player_id={player_id} lifecycleState={lifecycleState} itemImages={itemImages} item_results={item_results}
                                rounds={rounds} onCancelBid={handleCancelBid} onUpdateBid={handleUpdateBid} cancelLoading={bidLoading}
                                auctionExpired={auctionExpired} listHeader={statusBar} />
                        )}
                        {activeTab === 'players' && (
                            <SealedBidPlayersTab participants={participants} players={players} player_id={player_id} presence={presence}
                                socketConnected={socketConnected} market_type={competition.market_type} lifecycleState={lifecycleState}
                                listHeader={statusBar} />
                        )}
                        {activeTab === 'results' && (
                            <CalcuttaRoundResults rounds={rounds} items={items} item_results={item_results} payout_rules={payout_rules}
                                market_type={competition.market_type} total_pot={Number(competition.total_pot) || 0}
                                unclaimed_pot={Number(competition.unclaimed_pot) || 0} />
                        )}
                        {activeTab === 'leaderboard' && (
                            <CalcuttaLeaderboard participants={participants} players={players} player_id={player_id}
                                market_type={competition.market_type} listHeader={statusBar} />
                        )}
                        {activeTab === 'info' && (
                            <SealedBidInfoTab competition={competition} rounds={rounds} payout_rules={payout_rules} escrow={escrow}
                                market_type={competition.market_type} player_balance={player_balance} onDepositFunds={onDepositFunds}
                                onEscrowUpdate={handleEscrowUpdate} lifecycleState={lifecycleState} />
                        )}
                    </View>
                </>
            )}

            <EscrowBottomSheet
                visible={escrowSheetVisible} onDismiss={() => setEscrowSheetVisible(false)}
                calcutta_competition_id={calcutta_competition_id} escrow={escrow} market_type={competition.market_type}
                max_escrow={competition.max_escrow} player_balance={player_balance} onDepositFunds={onDepositFunds}
                lifecycleState={lifecycleState} onUpdate={() => { handleEscrowUpdate(); setEscrowSheetVisible(false); }}
            />

            <AuctionResultsModal visible={showResultsModal} onDismiss={handleResultsDismiss} wonItems={wonItems} market_type={competition.market_type} />
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    loadingContainer: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
        padding: 40,
    },
    joinBanner: {
        marginHorizontal: 12,
        marginTop: 10,
        padding: 14,
        borderRadius: 12,
        borderWidth: 1,
    },
    joinInfo: {
        flexDirection: 'row',
        alignItems: 'center',
    },
    joinBtn: {
        marginTop: 12,
        height: 44,
        borderRadius: 10,
        alignItems: 'center',
        justifyContent: 'center',
    },
    tabContent: {
        flex: 1,
    },
    desktopPanel: {
        borderRadius: 12,
        borderWidth: 1,
        padding: 8,
    },
});
