// ===========================================================================
// FILE: lib/services/multiplayer_service.dart
// ===========================================================================

import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:share_plus/share_plus.dart';

class MultiplayerService {
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  final FirebaseAuth _auth = FirebaseAuth.instance;

  CollectionReference get _gamesCollection => _firestore.collection('games');

  Future<String> createGameRoom(int boardRadius, String hostName, String shapeName, bool isTimeMode, {bool isPublic = true}) async {
    String roomCode = _generateRoomCode();
    int randomSeed = Random().nextInt(1000000);

    await _gamesCollection.doc(roomCode).set({
      'status': 'waiting',
      'radius': boardRadius,
      'createdAt': FieldValue.serverTimestamp(),
      'players': ['host'],
      'turn': 'host',
      'moves': [],
      'seed': randomSeed,
      'hostName': hostName,
      'hostUid': _auth.currentUser?.uid, // NUOVO: Salviamo l'ID univoco del creatore
      'guestName': '',
      'shape': shapeName,
      'timeMode': isTimeMode,
      'isPublic': isPublic,
      'p1_reaction': null,
      'p2_reaction': null,
      'p1_rematch': false,
      'p2_rematch': false,
    });

    return roomCode;
  }

  Future<Map<String, dynamic>?> joinGameRoom(String roomCode, String guestName) async {
    DocumentSnapshot doc = await _gamesCollection.doc(roomCode).get();

    if (doc.exists && doc['status'] == 'waiting') {
      await _gamesCollection.doc(roomCode).update({
        'status': 'playing',
        'players': FieldValue.arrayUnion(['guest']),
        'guestName': guestName,
      });
      return doc.data() as Map<String, dynamic>;
    }
    return null;
  }

  Stream<QuerySnapshot> getPublicRooms() {
    return _gamesCollection
        .where('status', isEqualTo: 'waiting')
        .where('isPublic', isEqualTo: true)
        .snapshots();
  }

  void shareInviteLink(String roomCode) {
    String message = "Ehi! Giochiamo a TetraQ? 🎮\nCopia questo intero messaggio e apri l'app per entrare direttamente, oppure inserisci manualmente il codice: $roomCode";
    Share.share(message);
  }

  Stream<DocumentSnapshot> listenToRoom(String roomCode) {
    return _gamesCollection.doc(roomCode).snapshots();
  }

  String _generateRoomCode() {
    const chars = 'ACDEFGHJKLMNPQRSTUVWXYZ2345679';
    final random = Random();
    return String.fromCharCodes(Iterable.generate(
      5, (_) => chars.codeUnitAt(random.nextInt(chars.length)),
    ));
  }

  Future<void> sendReaction(String roomCode, bool isHost, String reaction) async {
    try {
      String prefix = isHost ? 'p1' : 'p2';
      await _gamesCollection.doc(roomCode).update({
        '${prefix}_reaction': reaction,
        '${prefix}_reaction_time': FieldValue.serverTimestamp(),
      });
    } catch (e) {
      debugPrint("Errore invio reazione: $e");
    }
  }

  Future<void> requestRematch(String roomCode, bool isHost) async {
    try {
      String prefix = isHost ? 'p1' : 'p2';
      await _gamesCollection.doc(roomCode).update({
        '${prefix}_rematch': true,
      });
    } catch (e) {
      debugPrint("Errore richiesta rivincita: $e");
    }
  }

  Future<void> resetMatch(String roomCode, int newRadius, String newShape, int newSeed) async {
    try {
      await _gamesCollection.doc(roomCode).update({
        'status': 'playing',
        'moves': [],
        'seed': newSeed,
        'radius': newRadius,
        'shape': newShape,
        'p1_rematch': false,
        'p2_rematch': false,
        'p1_reaction': null,
        'p2_reaction': null,
      });
    } catch (e) {
      debugPrint("Errore reset partita: $e");
    }
  }
}