import { useState } from 'react';
import { Alert, Pressable, ScrollView, StyleSheet, TextInput, View } from 'react-native';

import { Card } from '@/components/card';
import { PlayerAvatar } from '@/components/player-avatar';
import { Screen } from '@/components/screen';
import { ThemedText } from '@/components/themed-text';
import { Fonts, Spacing } from '@/constants/theme';
import { useTheme } from '@/hooks/use-theme';
import { presentLocalNotification } from '@/lib/notifications';
import { decideWinner, useStore } from '@/lib/store';
import type { PlayerId } from '@/lib/types';

function ScoreStepper({
  playerId,
  value,
  onChange,
}: {
  playerId: PlayerId;
  value: string;
  onChange: (next: string) => void;
}) {
  const theme = useTheme();
  const { state } = useStore();
  const player = state.players[playerId];

  const bump = (delta: number) => {
    const current = parseInt(value, 10) || 0;
    onChange(String(Math.max(0, current + delta)));
  };

  return (
    <Card style={styles.stepperCard}>
      <View style={styles.stepperHead}>
        <PlayerAvatar playerId={playerId} initial={player.name.charAt(0)} size={26} />
        <ThemedText type="smallBold">{player.name}</ThemedText>
        <ThemedText type="small" themeColor="textSecondary">
          · {player.alias}
        </ThemedText>
      </View>
      <View style={[styles.stepper, { backgroundColor: theme.backgroundSelected }]}>
        <Pressable
          onPress={() => bump(-1)}
          style={({ pressed }) => [
            styles.stepBtn,
            { backgroundColor: theme.backgroundElement, borderColor: theme.border },
            pressed && { opacity: 0.6 },
          ]}>
          <ThemedText style={styles.stepBtnText}>−</ThemedText>
        </Pressable>
        <TextInput
          value={value}
          onChangeText={(text) => onChange(text.replace(/[^0-9]/g, ''))}
          keyboardType="number-pad"
          selectTextOnFocus
          style={[styles.stepValue, { color: theme.text }]}
        />
        <Pressable
          onPress={() => bump(1)}
          style={({ pressed }) => [
            styles.stepBtn,
            { backgroundColor: theme.backgroundElement, borderColor: theme.border },
            pressed && { opacity: 0.6 },
          ]}>
          <ThemedText style={styles.stepBtnText}>＋</ThemedText>
        </Pressable>
      </View>
    </Card>
  );
}

export default function LogScoreScreen() {
  const theme = useTheme();
  const { state, actions } = useStore();
  const [posting, setPosting] = useState(false);
  const [gameId, setGameId] = useState(state.games[0]?.id ?? '');
  const [p1Score, setP1Score] = useState('0');
  const [p2Score, setP2Score] = useState('0');
  const [note, setNote] = useState('');

  // Fall back to the first game until the user picks one (games arrive async).
  const game = state.games.find((g) => g.id === gameId) ?? state.games[0];
  const scores = { p1: parseInt(p1Score, 10) || 0, p2: parseInt(p2Score, 10) || 0 };
  const winnerId = game ? decideWinner(game.scoring, scores) : null;
  const winner = winnerId ? state.players[winnerId] : null;
  const margin = Math.abs(scores.p1 - scores.p2);

  const post = async () => {
    if (!game || posting) return;
    setPosting(true);
    try {
      const match = await actions.logMatch(game.id, scores, note);
      setP1Score('0');
      setP2Score('0');
      setNote('');

      const poster = state.players[state.settings.currentPlayerId];
      // The server pushes to the other phone; this local ping mirrors it here
      // (and is all you see in Expo Go, where remote push needs a dev build).
      presentLocalNotification(
        `${game.emoji} ${poster.name} logged ${game.name}`,
        `${scores.p1}–${scores.p2}${winner ? `, ${winner.name} wins` : ', a tie'}.${
          match.cheatCheckFlagged
            ? ' The house finds this score suspicious. Care to dispute? 🚩'
            : ' Standings updated… unless?'
        }`,
      );
      Alert.alert(
        'Score posted',
        `${game.name}: ${scores.p1}–${scores.p2}. ${
          winner ? `${winner.name} takes it.` : 'A tie. Rematch required.'
        }`,
      );
    } catch (err) {
      Alert.alert(
        'Could not post',
        err instanceof Error ? err.message : 'Server unreachable. The score is NOT saved.',
      );
    } finally {
      setPosting(false);
    }
  };

  return (
    <Screen title="Log a score">
      <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={styles.chips}>
        {state.games.map((g) => {
          const selected = g.id === game?.id;
          return (
            <Pressable
              key={g.id}
              onPress={() => setGameId(g.id)}
              style={[
                styles.chip,
                {
                  backgroundColor: selected ? theme.feltSoft : theme.backgroundElement,
                  borderColor: selected ? theme.felt : theme.border,
                },
              ]}>
              <ThemedText
                type="smallBold"
                style={selected ? { color: theme.felt } : undefined}>
                {g.emoji} {g.name}
              </ThemedText>
            </Pressable>
          );
        })}
      </ScrollView>

      {game?.scoring === 'lowWins' ? (
        <ThemedText type="small" themeColor="textSecondary" style={styles.lowWinsNote}>
          {game.name} scores low-to-win — the smaller number takes it.
        </ThemedText>
      ) : null}

      <ScoreStepper playerId="p1" value={p1Score} onChange={setP1Score} />
      <ScoreStepper playerId="p2" value={p2Score} onChange={setP2Score} />

      <View style={[styles.winnerFlag, { backgroundColor: theme.feltSoft }]}>
        <ThemedText type="smallBold" style={{ color: theme.felt }}>
          {winner
            ? `🏆 ${winner.name} wins · margin ${margin}`
            : scores.p1 === scores.p2 && scores.p1 > 0
              ? '🤝 Dead tie — rematch?'
              : 'Enter both scores'}
        </ThemedText>
      </View>

      <TextInput
        value={note}
        onChangeText={setNote}
        placeholder="Add a note… “best of 3, she demanded a rematch”"
        placeholderTextColor={theme.textSecondary}
        multiline
        style={[
          styles.note,
          {
            color: theme.text,
            backgroundColor: theme.backgroundElement,
            borderColor: theme.border,
          },
        ]}
      />

      <Pressable
        onPress={post}
        disabled={!game || posting}
        style={({ pressed }) => [
          styles.postBtn,
          { backgroundColor: theme.felt },
          (pressed || posting) && { opacity: 0.8 },
        ]}>
        <ThemedText style={styles.postText}>{posting ? 'Posting…' : 'Post score'}</ThemedText>
      </Pressable>
      <ThemedText type="small" themeColor="textSecondary" style={styles.hint}>
        The other player gets a notification to confirm — or dispute.
      </ThemedText>
    </Screen>
  );
}

const styles = StyleSheet.create({
  chips: { gap: 8, paddingVertical: 2 },
  chip: {
    borderWidth: 1.5,
    borderRadius: 99,
    paddingHorizontal: 14,
    paddingVertical: 8,
  },
  lowWinsNote: { marginHorizontal: 4 },
  stepperCard: { gap: 8 },
  stepperHead: { flexDirection: 'row', alignItems: 'center', gap: 8 },
  stepper: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    borderRadius: 12,
    padding: 8,
  },
  stepBtn: {
    width: 40,
    height: 40,
    borderRadius: 10,
    borderWidth: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  stepBtnText: { fontSize: 18, fontWeight: '700' },
  stepValue: {
    flex: 1,
    textAlign: 'center',
    fontSize: 28,
    fontWeight: '800',
    fontFamily: Fonts?.mono,
    paddingVertical: 0,
  },
  winnerFlag: { borderRadius: 10, paddingVertical: 10, paddingHorizontal: 12 },
  note: {
    borderWidth: 1.5,
    borderRadius: 11,
    padding: 12,
    minHeight: 56,
    fontSize: 14,
    textAlignVertical: 'top',
  },
  postBtn: {
    borderRadius: 13,
    paddingVertical: 14,
    alignItems: 'center',
    marginTop: Spacing.one,
  },
  postText: { color: '#FFFFFF', fontWeight: '800', fontSize: 15 },
  hint: { textAlign: 'center', fontSize: 12 },
});
