import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'global_data.dart';
import 'cid_data_manager.dart';
import 'security_service.dart';

class ScambioDatiScreen extends StatefulWidget {
  const ScambioDatiScreen({super.key});

  @override
  State<ScambioDatiScreen> createState() => _ScambioDatiScreenState();
}

class _ScambioDatiScreenState extends State<ScambioDatiScreen> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final MobileScannerController _cameraController = MobileScannerController();
  final TextEditingController _manualCodeController = TextEditingController();

  String? _codiceSessione;
  String? _chiaveSegreta;
  String? _shortCode; // IL PIN DI 6 LETTERE
  StreamSubscription? _streamSubscription;

  bool _isLoading = false;
  bool _scambioConcluso = false;

  @override
  void initState() {
    super.initState();

    // 🧹 AVVIO DEL NETTURBINO (con 10% di probabilità per non intasare il server)
    if (Random().nextInt(10) == 0) {
      _pulisciVecchieSessioni();
    }
    // RIMOZIONE DELLA SECONDA CHIAMATA LIBERA

    // LOGICA DI APERTURA INTELLIGENTE:
    // Lato A -> Inizia con la Fotocamera (Indice 1)
    // Lato B -> Inizia mostrando il QR (Indice 0)
    int initialIndex = (GlobalData.latoCorrente == 'A') ? 1 : 0;

    _tabController = TabController(length: 2, vsync: this, initialIndex: initialIndex);

    // Avvio automatico Host (prepara il QR in background a prescindere dalla Tab aperta)
    _avviaHost();
  }

  // --- 🧹 IL NETTURBINO (GARBAGE COLLECTOR) ---
  // Cerca nel database le sessioni più vecchie di 2 ore e le distrugge
  Future<void> _pulisciVecchieSessioni() async {
    try {
      final dueOreFa = DateTime.now().subtract(const Duration(hours: 2));

      final snapshot = await FirebaseFirestore.instance
          .collection('scambi_cid')
          .where('timestamp_scambio', isLessThan: Timestamp.fromDate(dueOreFa))
          .get();

      int cancellati = 0;
      for (var doc in snapshot.docs) {
        await doc.reference.delete();
        cancellati++;
      }

      debugPrint("🧹 [NETTURBINO] Pulizia completata: eliminate $cancellati sessioni vecchie.");
    } catch (e) {
      debugPrint("⚠️ [NETTURBINO] Errore durante la pulizia: $e");
    }
  }
  
  @override
  void dispose() {
    // Cancello la sessione se esco senza concludere, a meno che non sia l'ID della firma
    if (!_scambioConcluso && _codiceSessione != null && _codiceSessione != GlobalData.idSessione) {
      FirebaseFirestore.instance.collection('scambi_cid').doc(_codiceSessione).delete();
    }

    _streamSubscription?.cancel();
    _tabController.dispose();
    _cameraController.dispose();
    _manualCodeController.dispose();
    super.dispose();
  }

  // --- GENERATORE DI PIN A 6 LETTERE MAIUSCOLE ---
  String _generaShortCode() {
    const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
    Random rnd = Random();
    return String.fromCharCodes(Iterable.generate(6, (_) => chars.codeUnitAt(rnd.nextInt(chars.length))));
  }

  // --- 1. LOGICA HOST (CHI MOSTRA IL QR) ---
  Future<void> _avviaHost() async {
    if (_codiceSessione != null) return;

    if ((GlobalData.latoCorrente == 'A' && GlobalData.puntiFirmaA.isEmpty) ||
        (GlobalData.latoCorrente == 'B' && GlobalData.puntiFirmaB.isEmpty)) {
      return;
    }

    setState(() => _isLoading = true);

    try {
      String sessionId = GlobalData.idSessione ?? "CID_${DateTime.now().millisecondsSinceEpoch}";
      String shortCode = _generaShortCode();

      GlobalData.idSessione = sessionId;
      GlobalData.idScambioTemporaneo = sessionId;

      String chiave = GlobalData.chiaveSegretaCorrente ?? SecurityService.generaChiaveSessione();
      GlobalData.chiaveSegretaCorrente = chiave;

      Map<String, dynamic> mieiDati = CidDataManager.estraiDatiPerExport();
      String payloadCriptato = SecurityService.criptaDati(mieiDati, chiave);

      await FirebaseFirestore.instance.collection('scambi_cid').doc(sessionId).set({
        "timestamp_scambio": FieldValue.serverTimestamp(),
        "host_lato": GlobalData.latoCorrente,
        "secure_payload_host": payloadCriptato,
        "secure_payload_guest": null,
        "status": "waiting_guest",
        "short_code": shortCode,
        "chiave_temporanea": chiave
      }, SetOptions(merge: true));

      if (mounted) {
        setState(() {
          _codiceSessione = sessionId;
          _chiaveSegreta = chiave;
          _shortCode = shortCode;
          _isLoading = false;
        });
      }

      // Ascolto risposta dell'altro telefono
      _streamSubscription = FirebaseFirestore.instance.collection('scambi_cid').doc(sessionId).snapshots().listen((snapshot) {
        if (!snapshot.exists) {
          if (mounted) setState(() => _codiceSessione = null);
          return;
        }
        var data = snapshot.data();
        if (data != null && data['secure_payload_guest'] != null) {
          _streamSubscription?.cancel();
          _completaSync(data['secure_payload_guest'], chiave);
        }
      });

    } catch (e) {
      debugPrint("Err Host: $e");
      if (mounted) setState(() => _isLoading = false);
    }
  }

  void _completaSync(String encryptedData, String chiave) {
    try {
      Map<String, dynamic> dati = SecurityService.decriptaDati(encryptedData, chiave);
      CidDataManager.importaDati(dati);
      _scambioConcluso = true;
      _showSuccessAndExit();
    } catch (e) {
      if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Errore decriptazione")));
    }
  }

  // --- 2. LOGICA GUEST: VIA FOTOCAMERA ---
  void _onDetect(BarcodeCapture capture) {
    if (_isLoading || _scambioConcluso) return;

    final List<Barcode> barcodes = capture.barcodes;
    for (final barcode in barcodes) {
      if (barcode.rawValue != null) {
        _partecipaGuestScansione(barcode.rawValue!);
        break;
      }
    }
  }

  Future<void> _partecipaGuestScansione(String qrRawData) async {
    if (qrRawData.isEmpty) return;

    setState(() => _isLoading = true);

    try {
      if (!qrRawData.contains('|')) throw Exception("QR non valido");
      var parts = qrRawData.split('|');
      String sessionId = parts[0];
      String chiave = parts[1];

      await _eseguiPartecipazione(sessionId, chiave);
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Errore Scansione: $e")));
        await Future.delayed(const Duration(seconds: 2));
        setState(() => _isLoading = false);
      }
    }
  }

  // --- 3. LOGICA GUEST: INSERIMENTO MANUALE ---
  Future<void> _partecipaGuestManuale() async {
    String codiceInserito = _manualCodeController.text.trim().toUpperCase();

    if (codiceInserito.length < 5) {
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Inserisci un codice valido!"), backgroundColor: Colors.orange));
      return;
    }

    setState(() => _isLoading = true);

    try {
      // 1. Cerca la sessione tramite codice corto su Firebase
      final querySnapshot = await FirebaseFirestore.instance
          .collection('scambi_cid')
          .where('short_code', isEqualTo: codiceInserito)
          .limit(1)
          .get();

      if (querySnapshot.docs.isEmpty) {
        throw Exception("Codice non trovato o scaduto.");
      }

      final doc = querySnapshot.docs.first;
      String sessionId = doc.id;
      String chiave = doc['chiave_temporanea'] ?? "CHIAVE_DI_BACKUP";

      await _eseguiPartecipazione(sessionId, chiave, manualHostData: doc.data());

    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Errore: $e"), backgroundColor: Colors.red));
        setState(() => _isLoading = false);
      }
    }
  }

  // --- FUNZIONE CENTRALE PER GUEST (USATA DA FOTOCAMERA E MANUALE) ---
  Future<void> _eseguiPartecipazione(String sessionId, String chiave, {Map<String, dynamic>? manualHostData}) async {
    if (GlobalData.idSessione != null && GlobalData.idSessione != sessionId) {
      debugPrint("🗑️ Cancello vecchio file firma orfano: ${GlobalData.idSessione}");
      await FirebaseFirestore.instance.collection('scambi_cid').doc(GlobalData.idSessione).delete();
      GlobalData.idSessione = null;
    }

    Map<String, dynamic> data;

    if (manualHostData != null) {
      data = manualHostData;
    } else {
      DocumentSnapshot doc = await FirebaseFirestore.instance.collection('scambi_cid').doc(sessionId).get();
      if (!doc.exists) throw Exception("Sessione scaduta.");
      data = doc.data() as Map<String, dynamic>;
    }

    String? hostDataEnc = data['secure_payload_host'];
    if (hostDataEnc == null) throw Exception("Dati host mancanti.");

    Map<String, dynamic> datiHost = SecurityService.decriptaDati(hostDataEnc, chiave);
    CidDataManager.importaDati(datiHost);

    Map<String, dynamic> mieiDati = CidDataManager.estraiDatiPerExport();
    String myDataEnc = SecurityService.criptaDati(mieiDati, chiave);

    await FirebaseFirestore.instance.collection('scambi_cid').doc(sessionId).update({
      "secure_payload_guest": myDataEnc,
      "status": "completed"
    });

    GlobalData.idSessione = sessionId;
    GlobalData.idScambioTemporaneo = sessionId;
    GlobalData.chiaveSegretaCorrente = chiave;
    _scambioConcluso = true;

    _showSuccessAndExit();
  }

  void _showSuccessAndExit() {
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("SCAMBIO EFFETTUATO!"), backgroundColor: Colors.green, duration: Duration(seconds: 1))
    );
    Navigator.pop(context);
  }

  @override
  Widget build(BuildContext context) {
    String qrString = "";
    if (_codiceSessione != null && _chiaveSegreta != null) {
      qrString = "$_codiceSessione|$_chiaveSegreta";
    }

    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text("Scambio Dati"),
        backgroundColor: Colors.blue.shade900,
        foregroundColor: Colors.white,
        bottom: TabBar(
            controller: _tabController,
            indicatorColor: Colors.white,
            labelColor: Colors.white,
            unselectedLabelColor: Colors.white70,
            tabs: const [
              Tab(icon: Icon(Icons.qr_code), text: "IL TUO QR"),
              Tab(icon: Icon(Icons.camera_alt), text: "SCANSIONA / CODICE")
            ]
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        // Impedisce di strusciare accidentalmente e chiudere lo scanner
        physics: const NeverScrollableScrollPhysics(),
        children: [
          // ================= TAB 1: HOST (MOSTRA QR E PIN) =================
          Center(
              child: SingleChildScrollView(
                  child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        if (_codiceSessione == null) ...[
                          const CircularProgressIndicator(),
                          const SizedBox(height: 20),
                          const Text("Generazione in corso...")
                        ] else ...[
                          const Text("Fai scansionare questo QR:", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
                          const SizedBox(height: 20),
                          Container(
                              padding: const EdgeInsets.all(10),
                              decoration: BoxDecoration(color: Colors.white, border: Border.all(color: Colors.black12)),
                              child: QrImageView(data: qrString, size: 240)
                          ),
                          const SizedBox(height: 30),

                          const Text("Oppure fai inserire questo PIN:", style: TextStyle(color: Colors.black54)),
                          const SizedBox(height: 5),
                          Container(
                            padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
                            decoration: BoxDecoration(
                                color: Colors.orange.shade50,
                                borderRadius: BorderRadius.circular(10),
                                border: Border.all(color: Colors.orange.shade800, width: 2)
                            ),
                            child: Text(
                                _shortCode ?? "---",
                                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 32, letterSpacing: 6, color: Colors.orange.shade900)
                            ),
                          ),

                          const SizedBox(height: 30),
                          const CircularProgressIndicator(),
                          const SizedBox(height: 10),
                          const Text("In attesa dell'altro utente...", style: TextStyle(color: Colors.grey))
                        ]
                      ]
                  )
              )
          ),

          // ================= TAB 2: GUEST (SCANNER SPLIT SCREEN) =================
          Stack(
            children: [
              Column(
                children: [
                  // METÀ SUPERIORE: FOTOCAMERA
                  Expanded(
                    flex: 5,
                    child: Stack(
                      children: [
                        MobileScanner(
                          controller: _cameraController,
                          onDetect: _onDetect,
                        ),
                        // Overlay mirino per far capire all'utente dove inquadrare
                        Center(
                          child: Container(
                            width: 200, height: 200,
                            decoration: BoxDecoration(
                                border: Border.all(color: Colors.greenAccent, width: 3),
                                borderRadius: BorderRadius.circular(20)
                            ),
                          ),
                        ),
                        Positioned(
                            bottom: 10,
                            left: 0,
                            right: 0,
                            child: Container(
                              color: Colors.black54,
                              padding: const EdgeInsets.symmetric(vertical: 8),
                              child: const Text(
                                "Inquadra il QR Code",
                                textAlign: TextAlign.center,
                                style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
                              ),
                            )
                        )
                      ],
                    ),
                  ),

                  // DIVISORIO
                  Container(height: 5, color: Colors.blue.shade900),

                  // METÀ INFERIORE: INSERIMENTO MANUALE
                  Expanded(
                    flex: 5,
                    child: Container(
                      color: Colors.grey.shade100,
                      width: double.infinity,
                      child: SingleChildScrollView(
                        padding: const EdgeInsets.all(20),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            const Icon(Icons.keyboard, size: 40, color: Colors.blueGrey),
                            const SizedBox(height: 10),
                            const Text(
                              "La fotocamera non funziona?\nInserisci qui il PIN a 6 lettere dell'altro utente:",
                              textAlign: TextAlign.center,
                              style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black87),
                            ),
                            const SizedBox(height: 20),
                            TextField(
                              controller: _manualCodeController,
                              textCapitalization: TextCapitalization.characters,
                              maxLength: 6,
                              textAlign: TextAlign.center,
                              style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 24, letterSpacing: 8),
                              decoration: InputDecoration(
                                hintText: "PIN",
                                counterText: "",
                                border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)),
                                filled: true,
                                fillColor: Colors.white,
                                prefixIcon: const Icon(Icons.password, color: Colors.blueGrey),
                              ),
                            ),
                            const SizedBox(height: 20),
                            SizedBox(
                              width: double.infinity,
                              child: ElevatedButton.icon(
                                style: ElevatedButton.styleFrom(
                                  backgroundColor: Colors.orange.shade800,
                                  foregroundColor: Colors.white,
                                  padding: const EdgeInsets.symmetric(vertical: 16),
                                  shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
                                ),
                                onPressed: _partecipaGuestManuale,
                                icon: const Icon(Icons.download),
                                label: const Text("SCARICA DATI", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                              ),
                            )
                          ],
                        ),
                      ),
                    ),
                  )
                ],
              ),

              // OVERLAY CARICAMENTO
              if (_isLoading) const ColoredBox(color: Colors.black54, child: Center(child: CircularProgressIndicator(color: Colors.white))),
            ],
          )
        ],
      ),
    );
  }
}