import 'dart:async';
import 'dart:math' as math;
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';

class ShotRecord {
  final double relativeX;
  final double relativeY;
  final bool isMake;
  final String playerId; 
  final String playerName; 
  final String? zone;
  final int? points;

  ShotRecord({
    required this.relativeX, 
    required this.relativeY, 
    required this.isMake, 
    required this.playerId,
    required this.playerName,
    this.zone,
    this.points,
  });

  Map<String, dynamic> toJson() => {
    'relativeX': relativeX, 'relativeY': relativeY, 'isMake': isMake,
    'playerId': playerId, 'playerName': playerName, 'zone': zone, 'points': points,
  };

  factory ShotRecord.fromJson(Map<String, dynamic> json) => ShotRecord(
    relativeX: json['relativeX'], relativeY: json['relativeY'], isMake: json['isMake'],
    playerId: json['playerId'], playerName: json['playerName'], zone: json['zone'], points: json['points'],
  );
}

class PlacarController extends ChangeNotifier {
  final String gameId;
  final String myTeam;
  final String opponentTeam;

  PlacarController({
    required this.gameId, 
    required this.myTeam, 
    required this.opponentTeam, 
  });

  bool isLoading = true;
  bool isSaving = false;
  bool gameWasAlreadyFinished = false; 

  int myScore = 0;
  int opponentScore = 0;
  int myFouls = 0;
  int opponentFouls = 0;
  int currentQuarter = 1;
  int myTimeoutsUsed = 0;
  int opponentTimeoutsUsed = 0;

  String? myTeamDbId;
  String? oppTeamDbId;

  List<String> myCourt = [];
  List<String> myBench = [];
  List<String> oppCourt = [];
  List<String> oppBench = [];

  Map<String, String> playerNames = {}; 
  Map<String, String> playerNumbers = {};
  Map<String, Map<String, int>> playerStats = {};

  bool showMyBench = false;
  bool showOppBench = false;

  bool isSelectingShotLocation = false;
  String? pendingAction;
  String? pendingPlayerId; 
  List<ShotRecord> matchShots = [];
  
  List<String> playByPlay = [];

  ValueNotifier<Duration> durationNotifier = ValueNotifier(const Duration(minutes: 10));
  Timer? timer;
  bool isRunning = false;

  bool isCalibrating = false; 
  double hoopBaseX = 0.088;    
  double arcRadius = 0.459;    
  double cornerY = 0.440;      

  // 👇 NOVO: Temporizador para o Auto-Save não travar a App
  Timer? _autoSaveTimer;

  Future<void> loadPlayers() async {
    final supabase = Supabase.instance.client;
    try {
      await Future.delayed(const Duration(milliseconds: 1500)); 

      myCourt.clear(); myBench.clear(); oppCourt.clear(); oppBench.clear();
      playerNames.clear(); playerStats.clear(); playerNumbers.clear();
      matchShots.clear(); playByPlay.clear(); myFouls = 0; opponentFouls = 0;

      final gameResponse = await supabase.from('games').select().eq('id', gameId).single();
      
      myScore = int.tryParse(gameResponse['my_score']?.toString() ?? '0') ?? 0;
      opponentScore = int.tryParse(gameResponse['opponent_score']?.toString() ?? '0') ?? 0;
      
      int totalSeconds = int.tryParse(gameResponse['remaining_seconds']?.toString() ?? '600') ?? 600;
      durationNotifier.value = Duration(seconds: totalSeconds);
      
      myTimeoutsUsed = int.tryParse(gameResponse['my_timeouts']?.toString() ?? '0') ?? 0;
      opponentTimeoutsUsed = int.tryParse(gameResponse['opp_timeouts']?.toString() ?? '0') ?? 0;
      currentQuarter = int.tryParse(gameResponse['current_quarter']?.toString() ?? '1') ?? 1;
      
      gameWasAlreadyFinished = gameResponse['status'] == 'Terminado'; 

      if (gameResponse['play_by_play'] != null) {
        playByPlay = List<String>.from(gameResponse['play_by_play']);
      } else {
        playByPlay = [];
      }

      final teamsResponse = await supabase.from('teams').select('id, name').inFilter('name', [myTeam, opponentTeam]);
      for (var t in teamsResponse) {
        if (t['name'] == myTeam) myTeamDbId = t['id'];
        if (t['name'] == opponentTeam) oppTeamDbId = t['id'];
      }

      List<dynamic> myPlayers = myTeamDbId != null ? await supabase.from('members').select().eq('team_id', myTeamDbId!).eq('type', 'Jogador') : [];
      List<dynamic> oppPlayers = oppTeamDbId != null ? await supabase.from('members').select().eq('team_id', oppTeamDbId!).eq('type', 'Jogador') : [];

      final statsResponse = await supabase.from('player_stats').select().eq('game_id', gameId);
      final Map<String, dynamic> savedStats = {
        for (var item in statsResponse) item['member_id'].toString(): item
      };

      for (int i = 0; i < myPlayers.length; i++) {
        String dbId = myPlayers[i]['id'].toString();
        String name = myPlayers[i]['name'].toString();
        
        _registerPlayer(name: name, number: myPlayers[i]['number']?.toString() ?? "0", dbId: dbId, isMyTeam: true, isCourt: i < 5);

        if (savedStats.containsKey(dbId)) {
          var s = savedStats[dbId];
          _loadSavedPlayerStats(dbId, s);
          myFouls += (s['fls'] as int? ?? 0); 
        }
      }
      _padTeam(myCourt, myBench, "Jogador", isMyTeam: true);

      for (int i = 0; i < oppPlayers.length; i++) {
        String dbId = oppPlayers[i]['id'].toString();
        String name = oppPlayers[i]['name'].toString();
        
        _registerPlayer(name: name, number: oppPlayers[i]['number']?.toString() ?? "0", dbId: dbId, isMyTeam: false, isCourt: i < 5);

        if (savedStats.containsKey(dbId)) {
          var s = savedStats[dbId];
          _loadSavedPlayerStats(dbId, s);
          opponentFouls += (s['fls'] as int? ?? 0);
        }
      }
      _padTeam(oppCourt, oppBench, "Adversário", isMyTeam: false);

      final shotsResponse = await supabase.from('shot_locations').select().eq('game_id', gameId);
      for (var shotData in shotsResponse) {
        matchShots.add(ShotRecord(
          relativeX: double.parse(shotData['relative_x'].toString()),
          relativeY: double.parse(shotData['relative_y'].toString()),
          isMake: shotData['is_make'] == true,
          playerId: shotData['member_id'].toString(),
          playerName: shotData['player_name'].toString(),
          zone: shotData['zone']?.toString(),
          points: shotData['points'] != null ? int.parse(shotData['points'].toString()) : null,
        ));
      }

      await _loadLocalBackup();

      isLoading = false;
      notifyListeners(); 
    } catch (e) {
      debugPrint("Erro ao retomar jogo: $e");
      isLoading = false;
      notifyListeners();
    }
  }

  void _loadSavedPlayerStats(String dbId, Map<String, dynamic> s) {
    playerStats[dbId] = {
      "pts": s['pts'] ?? 0, "rbs": s['rbs'] ?? 0, "ast": s['ast'] ?? 0,
      "stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
      "fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
      "ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
      "p2m": s['p2m'] ?? 0, "p2a": s['p2a'] ?? 0, "p3m": s['p3m'] ?? 0, "p3a": s['p3a'] ?? 0,
      "so": s['so'] ?? 0, "il": s['il'] ?? 0, "li": s['li'] ?? 0,
      "pa": s['pa'] ?? 0, "tres_s": s['tres_seg'] ?? 0, "dr": s['dr'] ?? 0, 
      "min": (s['minutos_jogados'] ?? 0) ~/ 60,
      "sec": s['minutos_jogados'] ?? 0,
    };
  }

  void _registerPlayer({required String name, required String number, String? dbId, required bool isMyTeam, required bool isCourt}) {
    String id = dbId ?? "fake_${DateTime.now().millisecondsSinceEpoch}_${math.Random().nextInt(9999)}";
    
    playerNames[id] = name;
    playerNumbers[id] = number;
    
    playerStats[id] = {
      "pts": 0, "rbs": 0, "ast": 0, "stl": 0, "tov": 0, "blk": 0, 
      "fls": 0, "fgm": 0, "fga": 0, "ftm": 0, "fta": 0, "orb": 0, "drb": 0,
      "p2m": 0, "p2a": 0, "p3m": 0, "p3a": 0,
      "so": 0, "il": 0, "li": 0, "pa": 0, "tres_s": 0, "dr": 0, 
      "min": 0, "sec": 0
    };

    if (isMyTeam) {
      if (isCourt) myCourt.add(id); else myBench.add(id);
    } else {
      if (isCourt) oppCourt.add(id); else oppBench.add(id);
    }
  }

  void _padTeam(List<String> court, List<String> bench, String prefix, {required bool isMyTeam}) {
    while (court.length < 5) {
      _registerPlayer(name: "Sem $prefix ${court.length + 1}", number: "0", dbId: null, isMyTeam: isMyTeam, isCourt: true);
    }
  }

  // 👇 MÁGICA 1: O "Anti-Spam". Ele acumula as mudanças e só grava 1.5s depois de parares de clicar!
  void _scheduleAutoSave() {
    _autoSaveTimer?.cancel();
    _autoSaveTimer = Timer(const Duration(milliseconds: 1500), () {
      _saveLocalBackup();
    });
  }

  Future<void> _saveLocalBackup() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final backupData = {
        'myScore': myScore, 'opponentScore': opponentScore,
        'myFouls': myFouls, 'opponentFouls': opponentFouls,
        'currentQuarter': currentQuarter, 'duration': durationNotifier.value.inSeconds,
        'myTimeoutsUsed': myTimeoutsUsed, 'opponentTimeoutsUsed': opponentTimeoutsUsed,
        'playerStats': playerStats,
        'myCourt': myCourt, 'myBench': myBench, 'oppCourt': oppCourt, 'oppBench': oppBench,
        'matchShots': matchShots.map((s) => s.toJson()).toList(),
        'playByPlay': playByPlay, 
      };
      await prefs.setString('backup_$gameId', jsonEncode(backupData));
    } catch (e) {
      debugPrint("Erro no Auto-Save: $e");
    }
  }

  Future<void> _loadLocalBackup() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final String? backupString = prefs.getString('backup_$gameId');
      
      if (backupString != null) {
        final data = jsonDecode(backupString);
        
        myScore = data['myScore']; opponentScore = data['opponentScore'];
        myFouls = data['myFouls']; opponentFouls = data['opponentFouls'];
        currentQuarter = data['currentQuarter']; durationNotifier.value = Duration(seconds: data['duration']);
        myTimeoutsUsed = data['myTimeoutsUsed']; opponentTimeoutsUsed = data['opponentTimeoutsUsed'];
        
        myCourt = List<String>.from(data['myCourt']); myBench = List<String>.from(data['myBench']);
        oppCourt = List<String>.from(data['oppCourt']); oppBench = List<String>.from(data['oppBench']);
        
        Map<String, dynamic> decodedStats = data['playerStats'];
        playerStats = decodedStats.map((k, v) => MapEntry(k, Map<String, int>.from(v)));
        
        List<dynamic> decodedShots = data['matchShots'];
        matchShots = decodedShots.map((s) => ShotRecord.fromJson(s)).toList();
        
        playByPlay = List<String>.from(data['playByPlay'] ?? []); 
      }
    } catch (e) {
      debugPrint("Erro ao carregar Auto-Save: $e");
    }
  }

  void toggleTimer(BuildContext context) {
    if (isRunning) {
      timer?.cancel();
      _scheduleAutoSave(); 
    } else {
      timer = Timer.periodic(const Duration(seconds: 1), (timer) {
        if (durationNotifier.value.inSeconds > 0) {
          
          void addTimeToCourt(List<String> court) {
            for (String id in court) {
              if (playerStats.containsKey(id)) {
                int currentSec = playerStats[id]!["sec"] ?? 0;
                playerStats[id]!["sec"] = currentSec + 1;
                playerStats[id]!["min"] = (currentSec + 1) ~/ 60;
              }
            }
          }
          addTimeToCourt(myCourt);
          addTimeToCourt(oppCourt);

          // Avisa APENAS o relógio (e não a App inteira)
          durationNotifier.value -= const Duration(seconds: 1); 

        } else {
          timer.cancel();
          isRunning = false;
         if (currentQuarter < 4) {
           currentQuarter++; 
           durationNotifier.value = const Duration(minutes: 10); 
           myFouls = 0; opponentFouls = 0;
           myTimeoutsUsed = 0; opponentTimeoutsUsed = 0; 
           _scheduleAutoSave(); 
         } 
         notifyListeners(); 
        }
      });
    }
    isRunning = !isRunning;
    notifyListeners(); 
  }
  void useTimeout(bool isOpponent) {
    if (isOpponent) {
      if (opponentTimeoutsUsed < 3) opponentTimeoutsUsed++;
    } else {
      if (myTimeoutsUsed < 3) myTimeoutsUsed++;
    }
    isRunning = false;
    timer?.cancel();
    _scheduleAutoSave();
    notifyListeners();
  }

  void handleActionDrag(BuildContext context, String action, String playerData) {
    String playerId = playerData.replaceAll("player_my_", "").replaceAll("player_opp_", "");
    final stats = playerStats[playerId]!;
    final name = playerNames[playerId]!;

    if (stats["fls"]! >= 5 && action != "sub_foul") {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('🛑 $name atingiu 5 faltas e está expulso!'), backgroundColor: Colors.red));
      return;
    }

    if (action == "add_pts_2" || action == "add_pts_3" || action == "miss_2" || action == "miss_3") {
      pendingAction = action;
      pendingPlayerId = playerData;
      isSelectingShotLocation = true;
    } else {
      commitStat(action, playerData);
    }
    notifyListeners();
  }

  void handleSubbing(BuildContext context, String action, String courtPlayerId, bool isOpponent) {
    if (action.startsWith("bench_my_") && !isOpponent) {
      String benchPlayerId = action.replaceAll("bench_my_", "");
      if (playerStats[benchPlayerId]!["fls"]! >= 5) return; 
      int courtIndex = myCourt.indexOf(courtPlayerId);
      int benchIndex = myBench.indexOf(benchPlayerId);
      myCourt[courtIndex] = benchPlayerId;
      myBench[benchIndex] = courtPlayerId;
      showMyBench = false;
    }
    if (action.startsWith("bench_opp_") && isOpponent) {
      String benchPlayerId = action.replaceAll("bench_opp_", "");
      if (playerStats[benchPlayerId]!["fls"]! >= 5) return;
      int courtIndex = oppCourt.indexOf(courtPlayerId);
      int benchIndex = oppBench.indexOf(benchPlayerId);
      oppCourt[courtIndex] = benchPlayerId;
      oppBench[benchIndex] = courtPlayerId;
      showOppBench = false;
    }
    _scheduleAutoSave();
    notifyListeners();
  }

  void registerShotFromPopup(BuildContext context, String action, String targetPlayer, String zone, int points, double relativeX, double relativeY) {
    String playerId = targetPlayer.replaceAll("player_my_", "").replaceAll("player_opp_", "");
    bool isMake = action.startsWith("add_");
    String name = playerNames[playerId] ?? "Jogador";

    matchShots.add(ShotRecord(
      relativeX: relativeX, relativeY: relativeY, isMake: isMake, 
      playerId: playerId, playerName: name, zone: zone, points: points
    ));

    String finalAction = isMake ? "add_pts_$points" : "miss_$points";
    commitStat(finalAction, targetPlayer);
    notifyListeners();
  }

  void registerShotLocation(BuildContext context, Offset position, Size size) {
    if (pendingAction == null || pendingPlayerId == null) return;
    
    bool is3Pt = pendingAction!.contains("_3");
    bool is2Pt = pendingAction!.contains("_2");

    if (is3Pt || is2Pt) {
      bool isValid = _validateShotZone(position, size, is3Pt);
      if (!isValid) return; 
    }

    bool isMake = pendingAction!.startsWith("add_pts_");
    double relX = position.dx / size.width;
    double relY = position.dy / size.height;
    String pId = pendingPlayerId!.replaceAll("player_my_", "").replaceAll("player_opp_", "");

    matchShots.add(ShotRecord(relativeX: relX, relativeY: relY, isMake: isMake, playerId: pId, playerName: playerNames[pId]!));
    
    commitStat(pendingAction!, pendingPlayerId!);
    
    isSelectingShotLocation = false; pendingAction = null; pendingPlayerId = null;
    _scheduleAutoSave(); 
    notifyListeners();
  }

  bool _validateShotZone(Offset position, Size size, bool is3Pt) {
    double relX = position.dx / size.width;
    double relY = position.dy / size.height;

    bool isLeftHalf = relX < 0.5;
    double hoopX = isLeftHalf ? hoopBaseX : (1.0 - hoopBaseX);
    double hoopY = 0.50; 

    double aspectRatio = size.width / size.height;
    double distFromCenterY = (relY - hoopY).abs(); 

    bool isInside2Pts;

    if (distFromCenterY > cornerY) {
      double distToBaseline = isLeftHalf ? relX : (1.0 - relX);
      isInside2Pts = distToBaseline <= hoopBaseX; 
    } else {
      double dx = (relX - hoopX) * aspectRatio;
      double dy = (relY - hoopY);
      double distanceToHoop = math.sqrt((dx * dx) + (dy * dy));
      isInside2Pts = distanceToHoop < arcRadius;
    }

    if (is3Pt) return !isInside2Pts;
    return isInside2Pts;            
  }

  void cancelShotLocation() {
    isSelectingShotLocation = false; pendingAction = null; pendingPlayerId = null; notifyListeners();
  }

  void registerFoul(String committerData, String foulType, String victimData) {
    bool isOpponent = committerData.startsWith("player_opp_");
    String committerId = committerData.replaceAll("player_my_", "").replaceAll("player_opp_", "");
    final committerStats = playerStats[committerId]!;
    final committerName = playerNames[committerId] ?? "Jogador";

    committerStats["fls"] = committerStats["fls"]! + 1;
    if (isOpponent) opponentFouls++; else myFouls++;

    if (foulType == "Desqualificante") {
      committerStats["fls"] = 5; 
    }

    String logText = "cometeu Falta $foulType";

    if (victimData.isNotEmpty) {
      String victimId = victimData.replaceAll("player_my_", "").replaceAll("player_opp_", "");
      final victimStats = playerStats[victimId]!;
      final victimName = playerNames[victimId] ?? "Jogador";

      victimStats["so"] = victimStats["so"]! + 1;
      logText += " sobre $victimName ⚠️";
    } else {
      logText += " (Equipa/Banco) ⚠️";
    }

    String time = "${durationNotifier.value.inMinutes.toString().padLeft(2, '0')}:${durationNotifier.value.inSeconds.remainder(60).toString().padLeft(2, '0')}";
    playByPlay.insert(0, "P$currentQuarter - $time: $committerName $logText");

    _scheduleAutoSave();
    notifyListeners();
  }

  void commitStat(String action, String playerData) {
    bool isOpponent = playerData.startsWith("player_opp_");
    String playerId = playerData.replaceAll("player_my_", "").replaceAll("player_opp_", "");
    final stats = playerStats[playerId]!;
    final name = playerNames[playerId] ?? "Jogador"; 

    String logText = ""; 

    if (action.startsWith("add_pts_")) {
      int pts = int.parse(action.split("_").last);
      if (isOpponent) opponentScore += pts; else myScore += pts;
      stats["pts"] = stats["pts"]! + pts;
      if (pts == 2) { stats["fgm"] = stats["fgm"]! + 1; stats["fga"] = stats["fga"]! + 1; stats["p2m"] = stats["p2m"]! + 1; stats["p2a"] = stats["p2a"]! + 1; }
      if (pts == 3) { stats["fgm"] = stats["fgm"]! + 1; stats["fga"] = stats["fga"]! + 1; stats["p3m"] = stats["p3m"]! + 1; stats["p3a"] = stats["p3a"]! + 1; }
      if (pts == 1) { stats["ftm"] = stats["ftm"]! + 1; stats["fta"] = stats["fta"]! + 1; } 
      logText = "marcou $pts pontos 🏀";
    } 
    else if (action.startsWith("sub_pts_")) {
      int ptsToAnul = int.parse(action.split("_").last);
      
      int lastShotIndex = matchShots.lastIndexWhere((s) => 
        s.playerId == playerId && 
        s.isMake == true && 
        s.points == ptsToAnul
      );

      if (lastShotIndex != -1) {
        matchShots.removeAt(lastShotIndex);
        if (isOpponent) opponentScore -= ptsToAnul; else myScore -= ptsToAnul;
        stats["pts"] = stats["pts"]! - ptsToAnul;
        
        if (ptsToAnul == 2) {
          if(stats["p2m"]! > 0) stats["p2m"] = stats["p2m"]! - 1;
          if(stats["p2a"]! > 0) stats["p2a"] = stats["p2a"]! - 1;
          if(stats["fgm"]! > 0) stats["fgm"] = stats["fgm"]! - 1; 
          if(stats["fga"]! > 0) stats["fga"] = stats["fga"]! - 1; 
        } else if (ptsToAnul == 3) {
          if(stats["p3m"]! > 0) stats["p3m"] = stats["p3m"]! - 1;
          if(stats["p3a"]! > 0) stats["p3a"] = stats["p3a"]! - 1;
          if(stats["fgm"]! > 0) stats["fgm"] = stats["fgm"]! - 1; 
          if(stats["fga"]! > 0) stats["fga"] = stats["fga"]! - 1; 
        } else if (ptsToAnul == 1) {
          if(stats["ftm"]! > 0) stats["ftm"] = stats["ftm"]! - 1;
          if(stats["fta"]! > 0) stats["fta"] = stats["fta"]! - 1;
        }
        logText = "anulou cesto de $ptsToAnul pts ⏪";
      } else {
        return; 
      }
    }
    else if (action == "miss_1") { stats["fta"] = stats["fta"]! + 1; logText = "falhou lance livre ❌"; } 
    else if (action == "miss_2") { stats["fga"] = stats["fga"]! + 1; stats["p2a"] = stats["p2a"]! + 1; logText = "falhou lançamento de 2 ❌"; } 
    else if (action == "miss_3") { stats["fga"] = stats["fga"]! + 1; stats["p3a"] = stats["p3a"]! + 1; logText = "falhou lançamento de 3 ❌"; }
    else if (action == "add_orb") { stats["orb"] = stats["orb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; logText = "ganhou ressalto ofensivo 🔄"; } 
    else if (action == "add_drb") { stats["drb"] = stats["drb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; logText = "ganhou ressalto defensivo 🛡️"; } 
    else if (action == "add_ast") { stats["ast"] = stats["ast"]! + 1; logText = "fez uma assistência 🤝"; }
    else if (action == "add_stl") { stats["stl"] = stats["stl"]! + 1; logText = "roubou a bola 🥷"; }
    else if (action == "add_blk") { stats["blk"] = stats["blk"]! + 1; logText = "fez um desarme (bloco) ✋"; }
    
    else if (action == "add_so") { stats["so"] = stats["so"]! + 1; logText = "sofreu uma falta 🤕"; }
    else if (action == "add_il") { stats["il"] = stats["il"]! + 1; logText = "intercetou um lançamento 🛑"; }
    else if (action == "add_li") { stats["li"] = stats["li"]! + 1; logText = "teve o lançamento intercetado 🚫"; }
    
    else if (action == "add_tov") { stats["tov"] = stats["tov"]! + 1; logText = "fez um passe ruim 🤦"; }
    else if (action == "add_pa") { stats["pa"] = stats["pa"]! + 1; stats["tov"] = stats["tov"]! + 1; logText = "cometeu passos 🚶"; }
    else if (action == "add_3s") { stats["tres_s"] = stats["tres_s"]! + 1; stats["tov"] = stats["tov"]! + 1; logText = "violação de 3 segundos ⏱️"; }
    else if (action == "add_24s") { stats["tov"] = stats["tov"]! + 1; logText = "violação de 24 segundos ⏱️"; }
    else if (action == "add_dr") { stats["dr"] = stats["dr"]! + 1; stats["tov"] = stats["tov"]! + 1; logText = "fez drible duplo 🏀"; }
    
    else if (action == "sub_foul") {
      if (stats["fls"]! > 0) stats["fls"] = stats["fls"]! - 1;
      if (isOpponent) { if (opponentFouls > 0) opponentFouls--; } else { if (myFouls > 0) myFouls--; }
      logText = "teve falta anulada 🔄";
    }

    if (logText.isNotEmpty) {
      String time = "${durationNotifier.value.inMinutes.toString().padLeft(2, '0')}:${durationNotifier.value.inSeconds.remainder(60).toString().padLeft(2, '0')}";
      playByPlay.insert(0, "P$currentQuarter - $time: $name $logText");
    }

    _scheduleAutoSave(); 
    notifyListeners(); 
  }

  Future<void> saveGameStats(BuildContext context) async {
    final supabase = Supabase.instance.client;
    isSaving = true;
    notifyListeners();

    try {
      bool isGameFinishedNow = currentQuarter >= 4 && durationNotifier.value.inSeconds == 0;
      String newStatus = isGameFinishedNow ? 'Terminado' : 'Pausado';

      String topPtsName = '---'; int maxPts = -1;
      String topAstName = '---'; int maxAst = -1;
      String topRbsName = '---'; int maxRbs = -1;
      String mvpName = '---';    double maxMvpScore = -999.0;

      playerStats.forEach((playerId, stats) {
        int pts = stats['pts'] ?? 0;
        int ast = stats['ast'] ?? 0;
        int rbs = stats['rbs'] ?? 0;
        
        double minJogados = (stats['sec'] ?? 0) / 60.0;
        if (minJogados <= 0) minJogados = 40.0; 
        
        int tr = rbs;
        int br = stats['stl'] ?? 0;
        int bp = stats['tov'] ?? 0;
        int lFalhados = (stats['fga'] ?? 0) - (stats['fgm'] ?? 0);
        int llFalhados = (stats['fta'] ?? 0) - (stats['ftm'] ?? 0);
        
        double mvpScore = ((pts * 0.30) + (tr * 0.20) + (ast * 0.35) + (br * 0.15)) -
                          ((bp * 0.35) + (lFalhados * 0.30) + (llFalhados * 0.35));
        mvpScore = mvpScore * (minJogados / 40.0);

        String pName = playerNames[playerId] ?? '---';

        if (pts > maxPts && pts > 0) { maxPts = pts; topPtsName = '$pName ($pts)'; }
        if (ast > maxAst && ast > 0) { maxAst = ast; topAstName = '$pName ($ast)'; }
        if (rbs > maxRbs && rbs > 0) { maxRbs = rbs; topRbsName = '$pName ($rbs)'; }
        if (mvpScore > maxMvpScore) { maxMvpScore = mvpScore; mvpName = '$pName (${mvpScore.toStringAsFixed(1)})'; } 
      });

      await supabase.from('games').update({
        'my_score': myScore, 'opponent_score': opponentScore,
        'remaining_seconds': durationNotifier.value.inSeconds,
        'my_timeouts': myTimeoutsUsed, 'opp_timeouts': opponentTimeoutsUsed,
        'current_quarter': currentQuarter, 'status': newStatus,
        'top_pts_name': topPtsName, 'top_ast_name': topAstName,
        'top_rbs_name': topRbsName, 'mvp_name': mvpName,
        'play_by_play': playByPlay, 
      }).eq('id', gameId);

      List<Map<String, dynamic>> batchStats = [];
      playerStats.forEach((playerId, stats) {
        if (!playerId.startsWith("fake_")) {
          bool isMyTeamPlayer = myCourt.contains(playerId) || myBench.contains(playerId);
          batchStats.add({
            'game_id': gameId, 'member_id': playerId, 'team_id': isMyTeamPlayer ? myTeamDbId! : oppTeamDbId!,
            'pts': stats['pts'], 'rbs': stats['rbs'], 'ast': stats['ast'], 'stl': stats['stl'], 'blk': stats['blk'], 
            'tov': stats['tov'], 'fls': stats['fls'], 'fgm': stats['fgm'], 'fga': stats['fga'], 'ftm': stats['ftm'], 
            'fta': stats['fta'], 'orb': stats['orb'], 'drb': stats['drb'], 'p2m': stats['p2m'], 'p2a': stats['p2a'], 
            'p3m': stats['p3m'], 'p3a': stats['p3a'],
            'so': stats['so'], 'il': stats['il'], 'li': stats['li'], 'pa': stats['pa'], 'tres_seg': stats['tres_s'], 
            'dr': stats['dr'], 'minutos_jogados': stats['sec'],
          });
        }
      });

      await supabase.from('player_stats').delete().eq('game_id', gameId);
      if (batchStats.isNotEmpty) await supabase.from('player_stats').insert(batchStats);

      final prefs = await SharedPreferences.getInstance();
      await prefs.remove('backup_$gameId');

      if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Guardado com Sucesso!'), backgroundColor: Colors.green));

    } catch (e) {
      debugPrint("Erro ao gravar estatísticas: $e");
      if (context.mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Erro ao guardar: $e'), backgroundColor: Colors.red));
    } finally {
      isSaving = false;
      notifyListeners();
    }
  }

  @override
  void dispose() {
    timer?.cancel();
    _autoSaveTimer?.cancel();
    super.dispose();
  }
}