import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  View,
  Text,
  Image,
  TouchableOpacity,
  ActivityIndicator,
  Modal,
  Animated,
  StyleSheet,
  KeyboardAvoidingView,
  Platform,
} from 'react-native';
import { useDubsTheme } from '../theme';
import { useDubs } from '../../provider';
import { useCreateGame } from '../../hooks/useCreateGame';
import type { CreateGameMutationResult } from '../../hooks/useCreateGame';
import { useCredits } from '../../hooks/useCredits';
import type { UnifiedEvent } from '../../types';
import { SolSlider } from './SolSlider';
import { TeamButton } from './TeamButton';

export interface CreateGameSheetProps {
  visible: boolean;
  onDismiss: () => void;
  event: UnifiedEvent;
  /** Override team colors */
  homeColor?: string;
  awayColor?: string;
  /** Callbacks */
  onSuccess?: (result: CreateGameMutationResult) => void;
  onError?: (error: Error) => void;
  /** Called when the user taps a team card */
  onTeamSelect?: (team: 'home' | 'away') => void;
  /** Called on success (for sound/animation) */
  onCreateSuccess?: (result: CreateGameMutationResult) => void;
  /** Called on each slider tick */
  onSliderTick?: (value: number) => void;
  /** Max wager in SOL */
  maxWager?: number;
  /** Custom short-name function for team labels */
  shortName?: (name: string | null) => string;
}

const STATUS_LABELS: Record<string, string> = {
  building: 'Building transaction...',
  signing: 'Approve in wallet...',
  confirming: 'Confirming...',
  success: 'Game Created!',
};

function formatSol(n: number): string {
  return parseFloat(n.toFixed(9)).toString();
}

function toPng(url: string | null | undefined): string | null {
  if (!url) return null;
  return url.replace('/svg?', '/png?');
}

export function CreateGameSheet({
  visible,
  onDismiss,
  event,
  homeColor = '#3B82F6',
  awayColor = '#EF4444',
  onSuccess,
  onError,
  onTeamSelect,
  onCreateSuccess,
  onSliderTick,
  maxWager = 1,
  shortName,
}: CreateGameSheetProps) {
  const t = useDubsTheme();
  const { wallet } = useDubs();
  const mutation = useCreateGame();
  const { credits, refetch: refetchCredits } = useCredits();

  const [selectedTeam, setSelectedTeam] = useState<'home' | 'away' | null>(null);
  const [wager, setWager] = useState(0.01);
  const [showSuccess, setShowSuccess] = useState(false);
  const [useCredit, setUseCredit] = useState(false);

  const oldestCredit = credits.length > 0 ? credits[0] : null;
  // Compare in lamports to avoid float drift between credit.amountSOL and
  // the slider's wager value. The on-chain instruction requires exact
  // match anyway — if either side has a sub-lamport rounding error we'd
  // get a confusing on-chain failure instead of a clean toggle gate.
  const canUseCredit = !!oldestCredit; // Any 0.01 SOL credit covers the 0.01 SOL minimum buy-in

  const overlayOpacity = useRef(new Animated.Value(0)).current;
  const successScale = useRef(new Animated.Value(0)).current;
  const successOpacity = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(overlayOpacity, {
      toValue: visible ? 1 : 0,
      duration: 250,
      useNativeDriver: true,
    }).start();
  }, [visible]);

  useEffect(() => {
    if (visible) {
      setSelectedTeam(null);
      setWager(0.01);
      setShowSuccess(false);
      successScale.setValue(0);
      successOpacity.setValue(0);
      mutation.reset();
    }
  }, [visible]); // eslint-disable-line react-hooks/exhaustive-deps

  // Handle success
  useEffect(() => {
    if (mutation.status === 'success' && mutation.data) {
      setShowSuccess(true);
      onSuccess?.(mutation.data);
      onCreateSuccess?.(mutation.data);

      Animated.parallel([
        Animated.spring(successScale, { toValue: 1, friction: 4, tension: 80, useNativeDriver: true }),
        Animated.timing(successOpacity, { toValue: 1, duration: 300, useNativeDriver: true }),
      ]).start();

      const timer = setTimeout(() => {
        Animated.timing(successOpacity, { toValue: 0, duration: 300, useNativeDriver: true }).start(() => {
          onDismiss();
        });
      }, 2500);
      return () => clearTimeout(timer);
    }
  }, [mutation.status, mutation.data]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (mutation.status === 'error' && mutation.error) {
      onError?.(mutation.error);
    }
  }, [mutation.status, mutation.error]); // eslint-disable-line react-hooks/exhaustive-deps

  const opponents = event.opponents || [];
  const homeName = shortName ? shortName(opponents[0]?.name) : (opponents[0]?.name || 'Home');
  const awayName = shortName ? shortName(opponents[1]?.name) : (opponents[1]?.name || 'Away');

  const isMutating = mutation.status !== 'idle' && mutation.status !== 'success' && mutation.status !== 'error';
  const canCreate = selectedTeam !== null && !isMutating && mutation.status !== 'success';

  const handleCreate = useCallback(async () => {
    if (!selectedTeam || !wallet.publicKey) return;

    try {
      await mutation.execute({
        id: event.id,
        playerWallet: wallet.publicKey.toBase58(),
        teamChoice: selectedTeam,
        // When sponsoring, the on-chain instruction forces buy-in to
        // the credit's amount; pass that so client-side wager state
        // matches what gets recorded.
        wagerAmount: useCredit && oldestCredit ? oldestCredit.amountSOL : wager,
        useCredit: useCredit && canUseCredit ? true : undefined,
      });
      if (useCredit) refetchCredits();
    } catch {
      // Error captured in mutation state
    }
  }, [selectedTeam, wallet.publicKey, mutation.execute, event.id, wager, useCredit, oldestCredit, canUseCredit, refetchCredits]); // eslint-disable-line react-hooks/exhaustive-deps

  const statusLabel = STATUS_LABELS[mutation.status] || '';

  // Countdown
  const startTime = event.startTime ? new Date(event.startTime) : null;
  const timeLabel = startTime
    ? startTime.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' }) +
      ' at ' +
      startTime.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })
    : 'TBD';

  return (
    <Modal visible={visible} animationType="slide" transparent onRequestClose={onDismiss}>
      <Animated.View style={[styles.overlay, { opacity: overlayOpacity }]}>
        <TouchableOpacity style={styles.overlayTap} activeOpacity={1} onPress={onDismiss} />
      </Animated.View>

      {/* Success overlay */}
      {showSuccess && (
        <View style={styles.successOverlay}>
          <Animated.View style={[styles.successContent, { opacity: successOpacity, transform: [{ scale: successScale }] }]}>
            <Text style={styles.successEmoji}>🎯</Text>
            <Text style={styles.successTitle}>Game Created!</Text>
            <Text style={styles.successSub}>
              {formatSol(wager)} SOL on {selectedTeam === 'home' ? homeName : awayName}
            </Text>
          </Animated.View>
        </View>
      )}

      <KeyboardAvoidingView style={styles.keyboardView} behavior={Platform.OS === 'ios' ? 'padding' : undefined}>
        <View style={styles.sheetPositioner}>
          <View style={[styles.sheet, { backgroundColor: t.background }]}>
            {/* Drag handle */}
            <View style={styles.handleRow}>
              <View style={[styles.handle, { backgroundColor: t.textMuted }]} />
            </View>

            {/* Header */}
            <View style={styles.header}>
              <View>
                <Text style={[styles.headerTitle, { color: t.text }]}>Create Game</Text>
                <Text style={[styles.headerSub, { color: t.textMuted }]}>{timeLabel}</Text>
              </View>
              <TouchableOpacity onPress={onDismiss} activeOpacity={0.8}>
                <Text style={[styles.closeButton, { color: t.textMuted }]}>{'\u2715'}</Text>
              </TouchableOpacity>
            </View>

            {/* Team Selection */}
            <View style={styles.section}>
              <Text style={[styles.sectionLabel, { color: t.textSecondary }]}>Pick Your Side</Text>
              <View style={styles.teamsRow}>
                <TeamButton
                  name={homeName}
                  imageUrl={opponents[0]?.imageUrl}
                  odds="—"
                  bets={0}
                  color={homeColor}
                  selected={selectedTeam === 'home'}
                  onPress={() => { setSelectedTeam('home'); onTeamSelect?.('home'); }}
                  t={t}
                />
                <TeamButton
                  name={awayName}
                  imageUrl={opponents[1]?.imageUrl}
                  odds="—"
                  bets={0}
                  color={awayColor}
                  selected={selectedTeam === 'away'}
                  onPress={() => { setSelectedTeam('away'); onTeamSelect?.('away'); }}
                  t={t}
                />
              </View>
            </View>

            {/* Summary */}
            <View style={[styles.summaryCard, { backgroundColor: t.surface, borderColor: t.border }]}>
              <View style={styles.summaryRow}>
                <Text style={[styles.summaryLabel, { color: t.textMuted }]}>Your wager</Text>
                <Text style={[styles.summaryValue, { color: t.text }]}>{formatSol(wager)} SOL</Text>
              </View>
              <View style={[styles.summarySep, { backgroundColor: t.border }]} />
              <View style={styles.summaryRow}>
                <Text style={[styles.summaryLabel, { color: t.textMuted }]}>You're the first</Text>
                <Text style={[styles.summaryValue, { color: t.success }]}>Set the odds</Text>
              </View>
            </View>

            {/* Credit toggle — only when user has at least one credit */}
            {selectedTeam && canUseCredit && oldestCredit && (
              <TouchableOpacity
                style={[styles.creditRow, { backgroundColor: useCredit ? '#22C55E18' : t.surface, borderColor: useCredit ? '#22C55E' : t.border }]}
                activeOpacity={0.8}
                onPress={() => setUseCredit(v => !v)}
              >
                <View style={styles.creditRowText}>
                  <Text style={[styles.creditTitle, { color: useCredit ? '#22C55E' : t.text }]}>
                    🎁 Use my {formatSol(oldestCredit.amountSOL)} SOL credit
                  </Text>
                  <Text style={[styles.creditSub, { color: t.textMuted }]}>
                    {useCredit
                      ? 'Treasury covers rent + buy-in'
                      : `${credits.length} credit${credits.length === 1 ? '' : 's'} from your streak`}
                  </Text>
                </View>
                <View style={[styles.creditCheckbox, useCredit && { backgroundColor: '#22C55E', borderColor: '#22C55E' }]}>
                  {useCredit && <Text style={styles.creditCheck}>✓</Text>}
                </View>
              </TouchableOpacity>
            )}

            {/* SOL Slider — hidden when sponsoring (wager locked to credit) */}
            {selectedTeam && !useCredit && (
              <SolSlider
                value={wager}
                min={0.01}
                max={maxWager}
                step={0.01}
                accentColor={selectedTeam === 'home' ? homeColor : awayColor}
                onValueChange={setWager}
                onTick={onSliderTick}
              />
            )}

            {/* Error */}
            {mutation.error && (
              <View style={[styles.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }]}>
                <Text style={[styles.errorText, { color: t.errorText }]}>{mutation.error.message}</Text>
              </View>
            )}

            {/* CTA */}
            <TouchableOpacity
              style={[styles.ctaButton, { backgroundColor: canCreate ? t.accent : t.border }]}
              disabled={!canCreate}
              onPress={handleCreate}
              activeOpacity={0.8}
            >
              {isMutating ? (
                <View style={styles.ctaLoading}>
                  <ActivityIndicator size="small" color="#FFFFFF" />
                  <Text style={styles.ctaText}>{statusLabel}</Text>
                </View>
              ) : mutation.status === 'success' ? (
                <Text style={styles.ctaText}>Game Created!</Text>
              ) : (
                <Text style={[styles.ctaText, !canCreate && { opacity: 0.5 }]}>
                  {selectedTeam
                    ? `Create Game \u2014 ${formatSol(wager)} SOL`
                    : 'Pick a side to start'}
                </Text>
              )}
            </TouchableOpacity>
          </View>
        </View>
      </KeyboardAvoidingView>
    </Modal>
  );
}

const styles = StyleSheet.create({
  overlay: { ...StyleSheet.absoluteFillObject, backgroundColor: 'rgba(0,0,0,0.5)' },
  overlayTap: { flex: 1 },
  keyboardView: { flex: 1, justifyContent: 'flex-end' },
  sheetPositioner: { justifyContent: 'flex-end' },
  sheet: { borderTopLeftRadius: 24, borderTopRightRadius: 24, paddingHorizontal: 20, paddingBottom: 40 },
  handleRow: { alignItems: 'center', paddingTop: 10, paddingBottom: 8 },
  handle: { width: 36, height: 4, borderRadius: 2, opacity: 0.4 },
  header: { flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'space-between', paddingVertical: 8 },
  headerTitle: { fontSize: 20, fontWeight: '700' },
  headerSub: { fontSize: 13, marginTop: 2 },
  closeButton: { fontSize: 20, padding: 4 },

  section: { gap: 10, paddingTop: 12 },
  sectionLabel: { fontSize: 14, fontWeight: '600' },
  teamsRow: { flexDirection: 'row', gap: 12 },

  summaryCard: { marginTop: 12, borderRadius: 14, borderWidth: 1, overflow: 'hidden' },
  summaryRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingVertical: 12 },
  summaryLabel: { fontSize: 14 },
  summaryValue: { fontSize: 15, fontWeight: '700' },
  summarySep: { height: 1, marginHorizontal: 16 },

  errorBox: { marginTop: 12, borderRadius: 12, borderWidth: 1, padding: 12 },
  errorText: { fontSize: 13, fontWeight: '500' },

  ctaButton: { marginTop: 16, height: 54, borderRadius: 14, justifyContent: 'center', alignItems: 'center' },
  ctaText: { color: '#FFFFFF', fontSize: 16, fontWeight: '700' },
  ctaLoading: { flexDirection: 'row', alignItems: 'center', gap: 10 },

  creditRow: { flexDirection: 'row', alignItems: 'center', gap: 12, marginTop: 12, padding: 12, borderRadius: 12, borderWidth: 1.5 },
  creditRowText: { flex: 1, gap: 2 },
  creditTitle: { fontSize: 14, fontWeight: '700' },
  creditSub: { fontSize: 12, fontWeight: '500' },
  creditCheckbox: { width: 22, height: 22, borderRadius: 11, borderWidth: 2, borderColor: '#3A3A3C', alignItems: 'center', justifyContent: 'center' },
  creditCheck: { color: '#FFFFFF', fontSize: 14, fontWeight: '900' },

  successOverlay: { ...StyleSheet.absoluteFillObject, zIndex: 100, alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.85)' },
  successContent: { alignItems: 'center', gap: 12 },
  successEmoji: { fontSize: 64 },
  successTitle: { color: '#FFFFFF', fontSize: 28, fontWeight: '900' },
  successSub: { color: '#8E8E93', fontSize: 16 },
});
