import 'package:flutter/material.dart';
import 'package:farolero/l10n/generated/app_localizations.dart';
import '../modelos/inicio_partida_multijugador.dart';
import '../modelos/partida.dart';
import '../modelos/snapshot_partida_online.dart';
import '../servicios/servicio_nearby.dart';
import '../tema/componentes_farolero.dart';
import '../tema/tema_app.dart';
import 'pantalla_debate_cliente.dart';
import 'pantalla_fin_partida_online.dart';
import 'pantalla_notas_online.dart';
import 'pantalla_revision_palabra.dart';
import 'pantalla_votacion_cliente.dart';
import 'package:provider/provider.dart';

class PantallaResultadoOnline extends StatefulWidget {
  final SnapshotPartidaOnline snapshot;
  final List<JugadorInicioPartida> jugadoresControlados;
  final String? pistaCategoria;

  const PantallaResultadoOnline({
    super.key,
    required this.snapshot,
    required this.jugadoresControlados,
    this.pistaCategoria,
  });

  @override
  State<PantallaResultadoOnline> createState() => _PantallaResultadoOnlineState();
}

class _PantallaResultadoOnlineState extends State<PantallaResultadoOnline> {
  OnMensajeCallback? _listener;
  ServicioNearby? _nearby;
  late SnapshotPartidaOnline _snapshot;

  @override
  void initState() {
    super.initState();
    _snapshot = widget.snapshot;
    _listener = (endpointId, mensaje) {
      if (!mounted) return;
      if (mensaje.tipo == TipoMensaje.partidaFin) {
        _abrirFin(mensaje.datos);
        return;
      }
      if (mensaje.tipo == TipoMensaje.votacionResultado) {
        setState(() => _snapshot = SnapshotPartidaOnline.fromJson(mensaje.datos));
        return;
      }
      if (mensaje.tipo != TipoMensaje.fase) return;
      final fase = mensaje.datos['fase'] as String?;
      if (fase == 'debate') {
        _abrirDebate(mensaje.datos);
      } else if (fase == 'votacion') {
        _abrirVotacion(mensaje.datos);
      } else if (fase == 'adivinanza' || fase == 'resultado') {
        setState(() => _snapshot = SnapshotPartidaOnline.fromJson(mensaje.datos));
      } else if (fase == 'finPartida') {
        _abrirFin(mensaje.datos);
      }
    };
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final listener = _listener;
      if (listener != null && mounted) {
        _nearby = context.read<ServicioNearby>();
        _nearby!.onMensaje(listener);
      }
    });
  }

  @override
  void dispose() {
    final listener = _listener;
    if (listener != null) {
      _nearby?.removeMensajeListener(listener);
    }
    super.dispose();
  }

  void _abrirDebate(Map<String, dynamic> datos) {
    final snapshot = SnapshotPartidaOnline.fromJson(datos);
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) => PantallaDebateCliente(
          tiempoDebateSegundos: datos['tiempoDebateSegundos'] as int?,
          primerTurnoNombre: datos['primerTurnoNombre'] as String?,
          partidaId: snapshot.roomId,
          pistaCategoria: widget.pistaCategoria,
          jugadores: snapshot.jugadores,
          jugadoresControlados: widget.jugadoresControlados,
          onSolicitarVotacion: _solicitarVotacion,
        ),
      ),
    );
  }

  void _abrirVotacion(Map<String, dynamic> datos) {
    final snapshot = SnapshotPartidaOnline.fromJson(datos);
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) => PantallaVotacionCliente(
          jugadores: snapshot.jugadores,
          jugadoresControlados: widget.jugadoresControlados,
          partidaId: snapshot.roomId,
          pistaCategoria: widget.pistaCategoria,
          onVotos: _enviarVotos,
        ),
      ),
    );
  }

  void _abrirFin(Map<String, dynamic> datos) {
    final snapshot = SnapshotPartidaOnline.fromJson(datos);
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(
        builder: (_) => PantallaFinPartidaOnline(
          snapshot: snapshot,
          jugadoresControlados: widget.jugadoresControlados,
          pistaCategoria: widget.pistaCategoria,
        ),
      ),
    );
  }

  void _solicitarVotacion() {
    final nearby = context.read<ServicioNearby>();
    if (nearby.hostEndpointId == null) return;
    nearby.enviarMensaje(
      nearby.hostEndpointId!,
      MensajeP2P(
        tipo: TipoMensaje.ping,
        datos: {'solicitoVotacion': true},
      ),
    );
  }

  void _enviarVotos(Map<String, String> votos) {
    final nearby = context.read<ServicioNearby>();
    if (nearby.hostEndpointId == null) return;
    for (final entry in votos.entries) {
      nearby.enviarMensaje(
        nearby.hostEndpointId!,
        MensajeP2P(
          tipo: TipoMensaje.voto,
          datos: {
            'votanteId': entry.key,
            'votadoId': entry.value,
            'votoporId': entry.value,
          },
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;
    final resultado = _snapshot.resultadoActual;

    return Scaffold(
      backgroundColor: TemaApp.colorFondo,
      appBar: AppBar(
        title: Text(_snapshot.fase == 'adivinanza'
            ? l10n.impostorGuessTitle
            : l10n.result),
        automaticallyImplyLeading: false,
        backgroundColor: Colors.transparent,
        elevation: 0,
        actions: _acciones(context, l10n),
      ),
      body: FondoFarolero(
        intenso: true,
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: resultado == null
              ? _buildEsperaAdivinanza(context, l10n)
              : _buildResultado(context, l10n, resultado),
        ),
      ),
    );
  }

  List<Widget> _acciones(BuildContext context, AppLocalizations l10n) => [
        IconButton(
          tooltip: l10n.seeYourWord,
          icon: const Icon(Icons.visibility),
          onPressed: widget.jugadoresControlados.isEmpty
              ? null
              : () => mostrarRevisionPalabraOnline(
                    context: context,
                    jugadoresControlados: widget.jugadoresControlados,
                    pistaCategoria: widget.pistaCategoria,
                  ),
        ),
        IconButton(
          tooltip: l10n.notesTitle,
          icon: const Icon(Icons.edit_note),
          onPressed: _snapshot.roomId == null || widget.jugadoresControlados.isEmpty
              ? null
              : () => Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (_) => PantallaNotasOnline(
                        partidaId: _snapshot.roomId!,
                        jugadores: _snapshot.jugadores,
                        autoresControlados: widget.jugadoresControlados,
                      ),
                    ),
                  ),
        ),
      ];

  Widget _buildEsperaAdivinanza(
    BuildContext context,
    AppLocalizations l10n,
  ) {
    return Center(
      child: Card(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              const Icon(Icons.hourglass_top, size: 48),
              const SizedBox(height: 16),
              Text(
                _snapshot.mensaje ?? l10n.impostorCanGuess,
                textAlign: TextAlign.center,
                style: Theme.of(context).textTheme.titleLarge,
              ),
              const SizedBox(height: 12),
              Text(
                l10n.waitingForHost,
                textAlign: TextAlign.center,
                style: TextStyle(color: TemaApp.colorTextoSecundario),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildResultado(
    BuildContext context,
    AppLocalizations l10n,
    ResultadoVotacion resultado,
  ) {
    final conteo = <String, int>{};
    for (final votadoId in resultado.votos.values) {
      conteo[votadoId] = (conteo[votadoId] ?? 0) + 1;
    }
    final maxVotos = conteo.values.isEmpty
        ? 1
        : conteo.values.reduce((a, b) => a > b ? a : b);
    final ranking = conteo.entries.toList()
      ..sort((a, b) => b.value.compareTo(a.value));
    final jugadores = {for (final jugador in _snapshot.jugadores) jugador.id: jugador};

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          width: double.infinity,
          padding: const EdgeInsets.all(20),
          decoration: TemaApp.decoracionPanel(
            color: resultado.eraImpostor
                ? TemaApp.colorVerde.withValues(alpha: 0.18)
                : TemaApp.colorAcento.withValues(alpha: 0.18),
            borderColor:
                resultado.eraImpostor ? TemaApp.colorVerde : TemaApp.colorAcento,
          ),
          child: Column(
            children: [
              Text(
                resultado.eliminadoNombre,
                style: Theme.of(context).textTheme.headlineMedium,
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 8),
              Text(
                resultado.eraImpostor ? l10n.wasImpostor : l10n.wasInnocent,
                style: TextStyle(
                  color: resultado.eraImpostor
                      ? TemaApp.colorVerde
                      : TemaApp.colorAcento,
                  fontWeight: FontWeight.bold,
                ),
              ),
              if (_snapshot.mensaje != null) ...[
                const SizedBox(height: 12),
                Text(_snapshot.mensaje!, textAlign: TextAlign.center),
              ],
            ],
          ),
        ),
        const SizedBox(height: 20),
        Text(l10n.votesThisRound, style: Theme.of(context).textTheme.titleLarge),
        const SizedBox(height: 12),
        Expanded(
          child: ListView(
            children: [
              ...ranking.map((entry) {
                final jugador = jugadores[entry.key];
                final destacado = entry.key == resultado.eliminadoId;
                final color = destacado ? TemaApp.colorAcento : TemaApp.colorNaranja;
                return Padding(
                  padding: const EdgeInsets.only(bottom: 12),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          Expanded(child: Text(jugador?.nombre ?? '?')),
                          Text(
                            '${entry.value}',
                            style: TextStyle(
                              color: color,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 6),
                      ClipRRect(
                        borderRadius: BorderRadius.circular(999),
                        child: LinearProgressIndicator(
                          value: (entry.value / maxVotos).clamp(0.0, 1.0).toDouble(),
                          minHeight: 10,
                          backgroundColor: TemaApp.colorSuperficie,
                          valueColor: AlwaysStoppedAnimation(color),
                        ),
                      ),
                    ],
                  ),
                );
              }),
              const Divider(height: 24),
              ...resultado.votos.entries.map((entry) {
                final votante = jugadores[entry.key]?.nombre ?? '?';
                final votado = jugadores[entry.value]?.nombre ?? '?';
                return ListTile(
                  dense: true,
                  leading: const Icon(Icons.how_to_vote),
                  title: Text('$votante → $votado'),
                );
              }),
            ],
          ),
        ),
      ],
    );
  }
}
