import React, { useState, useMemo, useCallback } from 'react';
import { StyleSheet, Text, TouchableOpacity, type ViewStyle } from 'react-native';
import { useDubsTheme } from '../theme';
import { useDubs } from '../../provider';
import { useGame } from '../../hooks/useGame';
import { useHasClaimed } from '../../hooks/useHasClaimed';
import { ClaimPrizeSheet } from './ClaimPrizeSheet';
import type { ClaimMutationResult } from '../../hooks/useClaim';

export interface ClaimButtonProps {
  gameId: string;
  style?: ViewStyle;
  onSuccess?: (result: ClaimMutationResult) => void;
  onError?: (error: Error) => void;
}

/**
 * Drop-in claim button that handles eligibility checks, prize/refund display,
 * and the claim sheet lifecycle internally.
 *
 * Renders nothing when the user is ineligible (lost, not resolved, not a bettor, etc.).
 */
export function ClaimButton({ gameId, style, onSuccess, onError }: ClaimButtonProps) {
  const t = useDubsTheme();
  const { wallet } = useDubs();
  const game = useGame(gameId);
  const claimStatus = useHasClaimed(gameId);
  const [sheetVisible, setSheetVisible] = useState(false);

  const walletAddress = wallet.publicKey?.toBase58() ?? null;

  const myBet = useMemo(() => {
    if (!walletAddress || !game.data?.bettors) return null;
    return game.data.bettors.find(b => b.wallet === walletAddress) ?? null;
  }, [walletAddress, game.data?.bettors]);

  const isResolved = game.data?.isResolved ?? false;
  const isRefund = isResolved && game.data?.winnerSide === null;
  const isWinner = isResolved && myBet != null && myBet.team === game.data?.winnerSide;
  const isEligible = myBet != null && isResolved && (isWinner || isRefund);
  const prizeAmount = isRefund ? (myBet?.amount ?? 0) : (game.data?.totalPool ?? 0);

  const handleSuccess = useCallback(
    (result: ClaimMutationResult) => {
      claimStatus.refetch();
      onSuccess?.(result);
    },
    [claimStatus.refetch, onSuccess], // eslint-disable-line react-hooks/exhaustive-deps
  );

  // Don't render while loading or missing wallet/data
  if (game.loading || claimStatus.loading || !game.data || !walletAddress) {
    return null;
  }

  const label = isRefund ? 'Refund' : 'Prize';

  // Already claimed — always show badge regardless of eligibility computation
  if (claimStatus.hasClaimed) {
    return (
      <TouchableOpacity
        style={[styles.badge, { borderColor: t.accent }, style]}
        activeOpacity={1}
        disabled
      >
        <Text style={[styles.badgeText, { color: t.accent }]}>
          {label} Claimed!
        </Text>
      </TouchableOpacity>
    );
  }

  // Not eligible (lost, not resolved, not a bettor) — render nothing
  if (!isEligible) {
    return null;
  }

  return (
    <>
      <TouchableOpacity
        style={[styles.button, { backgroundColor: t.accent }, style]}
        activeOpacity={0.8}
        onPress={() => setSheetVisible(true)}
      >
        <Text style={styles.buttonText}>
          Claim {label} — {prizeAmount} SOL
        </Text>
      </TouchableOpacity>

      <ClaimPrizeSheet
        visible={sheetVisible}
        onDismiss={() => setSheetVisible(false)}
        gameId={gameId}
        prizeAmount={prizeAmount}
        isRefund={isRefund}
        onSuccess={handleSuccess}
        onError={onError}
      />
    </>
  );
}

const styles = StyleSheet.create({
  button: {
    height: 52,
    borderRadius: 14,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 20,
  },
  buttonText: {
    color: '#FFFFFF',
    fontSize: 16,
    fontWeight: '700',
  },
  badge: {
    height: 52,
    borderRadius: 14,
    borderWidth: 2,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 20,
  },
  badgeText: {
    fontSize: 16,
    fontWeight: '700',
  },
});
