import 'package:flutter/material.dart';
import 'package:farolero/l10n/generated/app_localizations.dart';
import 'package:provider/provider.dart';
import '../estado/estado_juego.dart';
import '../modelos/inicio_partida_multijugador.dart';
import '../modelos/palabra.dart';
import '../modelos/partida.dart';
import '../servicios/servicio_nearby.dart';
import '../servicios/servicio_permisos.dart';
import '../servicios/servicio_perfil_usuario.dart';
import '../tema/componentes_farolero.dart';
import '../tema/tema_app.dart';
import 'pantalla_gestor_host.dart';
import 'pantalla_lobby_host.dart';
import 'pantalla_principal.dart';
import 'pantalla_ver_palabra.dart';

class PantallaCrearPartida extends StatefulWidget {
  final bool modoInicial;
  final bool bloquearModo;

  const PantallaCrearPartida({
    super.key,
    this.modoInicial = false,
    this.bloquearModo = false,
  });

  @override
  State<PantallaCrearPartida> createState() => _PantallaCrearPartidaState();
}

class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
  bool _modoMultimovil = false;
  String _categoria = 'todas';
  int _numImpostores = 1;
  bool _pistaImpostor = false;
  int? _tiempoDebate;
  final List<String> _jugadores = [];
  final _controladorNombre = TextEditingController();
  bool _agregandoPerfilPendiente = false;

  final _opcionesTiempo = <int?>[null, 60, 120, 180, 300];

  @override
  void initState() {
    super.initState();
    _modoMultimovil = widget.modoInicial;
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) _agregarPerfilLocalSiNecesario();
    });
  }

  void _agregarPerfilLocalSiNecesario() {
    if (_modoMultimovil) return;
    final servicioPerfil = context.read<ServicioPerfilUsuario>();
    if (!servicioPerfil.cargado) return;
    final perfil = servicioPerfil.perfil;
    final nombre =
        perfil.nombre.trim().isEmpty ? 'Jugador' : perfil.nombre.trim();
    if (_jugadores.contains(nombre)) return;
    setState(() {
      _jugadores.insert(0, nombre);
    });
  }

  int get _maxImpostores =>
      _modoMultimovil ? 4 : (_jugadores.length / 3).floor().clamp(1, 4);

  List<String> _etiquetasTiempo(AppLocalizations l10n) => [
    l10n.noLimit,
    l10n.oneMin,
    l10n.twoMin,
    l10n.threeMin,
    l10n.fiveMin,
  ];

  void _agregarJugador() {
    final l10n = AppLocalizations.of(context)!;
    final nombre = _controladorNombre.text.trim();
    if (nombre.isEmpty) return;
    if (_jugadores.contains(nombre)) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text(l10n.playerAlreadyExists)));
      return;
    }
    if (_jugadores.length >= 20) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text(l10n.maxPlayersReached)));
      return;
    }
    setState(() {
      _jugadores.add(nombre);
      _controladorNombre.clear();
      if (_numImpostores > _maxImpostores) {
        _numImpostores = _maxImpostores;
      }
    });
  }

  void _eliminarJugador(int index) {
    final perfil = context.read<ServicioPerfilUsuario>().perfil;
    final nombrePerfil =
        perfil.nombre.trim().isEmpty ? 'Jugador' : perfil.nombre.trim();
    if (index == 0 && _jugadores[index] == nombrePerfil) return;
    setState(() {
      _jugadores.removeAt(index);
      if (_numImpostores > _maxImpostores && _maxImpostores > 0) {
        _numImpostores = _maxImpostores;
      }
    });
  }

  void _iniciarPartida() {
    final l10n = AppLocalizations.of(context)!;

    if (_modoMultimovil) {
      _iniciarPartidaMulti();
      return;
    }

    if (_jugadores.length < 3) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text(l10n.minPlayersRequired)));
      return;
    }

    final estado = context.read<EstadoJuego>();
    estado.crearPartida(
      config: ConfigPartida(
        modoMultimovil: false,
        categoria: _categoria,
        numImpostores: _numImpostores,
        pistaImpostor: _pistaImpostor,
        tiempoDebateSegundos: _tiempoDebate,
      ),
      nombresJugadores: _jugadores,
    );

    Navigator.pushReplacement(
      context,
      MaterialPageRoute(builder: (_) => const PantallaVerPalabra()),
    );
  }

  Future<void> _iniciarPartidaMulti() async {
    // 1. Pedir permisos automáticamente
    final permisosOk = await ServicioPermisos.solicitarPermisosNearby(context);
    if (!permisosOk) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('Se necesitan permisos de Bluetooth y ubicación'),
          ),
        );
      }
      return;
    }

    // 2. Usar el perfil principal del dispositivo como usuario del host.
    final nombre = await _seleccionarUsuarioHost();
    if (nombre == null || nombre.trim().isEmpty) return;

    // 3. Iniciar host en Nearby
    if (!mounted) return;
    final nearby = context.read<ServicioNearby>();
    final servicioPerfil = context.read<ServicioPerfilUsuario>();
    final perfil = servicioPerfil.perfil;
    final gamificacion = servicioPerfil.resumenGamificacion;
    final nombreSala = '${nombre.trim()} - Farolero';
    final ok = await nearby.iniciarHost(
      nombreSala,
      nombre.trim(),
      miNick: perfil.nick,
      miAvatar: perfil.avatarAsset,
      miFuego: gamificacion.fuego,
      miMedallas: gamificacion.medallas,
    );

    if (!ok) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('No se pudo crear la sala. Verifica Bluetooth.'),
          ),
        );
      }
      return;
    }

    // 4. Navegar al lobby con QR
    if (mounted) {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => PantallaLobbyHost(
            nombreSala: nombreSala,
            onIniciar: () {
              // Cuando el host toca "Iniciar" con suficientes jugadores
              final estado = context.read<EstadoJuego>();
              final sala = nearby.estadoSala;
              if (sala == null) return;
              final validacion = sala.iniciarPartida();
              if (!validacion.exitoso) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text(
                      'No se puede iniciar: ${validacion.codigo ?? "sala inválida"}',
                    ),
                  ),
                );
                return;
              }

              estado.crearPartidaDesdeSala(
                config: ConfigPartida(
                  modoMultimovil: true,
                  categoria: _categoria,
                  numImpostores: _numImpostores,
                  pistaImpostor: _pistaImpostor,
                  tiempoDebateSegundos: _tiempoDebate,
                ),
                sala: sala,
              );

              final partida = estado.partida!;
              final asignaciones = partida.jugadores.map((jugador) {
                final usuarioSala = sala.usuarios[jugador.id];
                final clientId = usuarioSala?.clienteIdSeleccionado;
                final cliente = clientId == null ? null : sala.clientes[clientId];
                return AsignacionJugador(
                  jugadorId: jugador.id,
                  nombre: jugador.nombre,
                  clientId: clientId ?? sala.hostClientId,
                  endpointId: cliente?.endpointId,
                );
              }).toList();
              final impostores = {
                for (final jugador in partida.jugadores)
                  jugador.id: jugador.esImpostor,
              };
              final jugadoresTodos = partida.jugadores
                  .map(
                    (jugador) => {
                      'id': jugador.id,
                      'nombre': jugador.nombre,
                      'eliminado': jugador.eliminado,
                    },
                  )
                  .toList();

              nearby.enviarInicioPartidaMulti(
                asignaciones: asignaciones,
                palabraSecreta: partida.palabraSecreta,
                categoria: _categoria,
                impostoresPorJugadorId: impostores,
                jugadoresTodos: jugadoresTodos,
              );

              Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (_) => PantallaGestorHost(
                    onPartidaFin: () {
                      estado.limpiar();
                      Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                          builder: (_) => const PantallaPrincipal(),
                        ),
                      );
                    },
                  ),
                ),
              );
            },
          ),
        ),
      );
    }
  }

  /// Devuelve el perfil principal del dispositivo para crear la sala.
  Future<String?> _seleccionarUsuarioHost() async {
    return context.read<ServicioPerfilUsuario>().perfil.nombre;
  }

  @override
  void dispose() {
    _controladorNombre.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;
    final estado = context.watch<EstadoJuego>();
    final servicioPerfil = context.watch<ServicioPerfilUsuario>();
    final categorias = ['todas', ...?estado.banco?.nombresCategorias];
    final etiquetas = _etiquetasTiempo(l10n);
    final nombrePerfilActual = servicioPerfil.perfil.nombre.trim().isEmpty
        ? 'Jugador'
        : servicioPerfil.perfil.nombre.trim();
    if (!_modoMultimovil &&
        servicioPerfil.cargado &&
        !_agregandoPerfilPendiente &&
        !_jugadores.contains(nombrePerfilActual)) {
      _agregandoPerfilPendiente = true;
      WidgetsBinding.instance.addPostFrameCallback((_) {
        _agregandoPerfilPendiente = false;
        if (mounted) _agregarPerfilLocalSiNecesario();
      });
    }

    return Scaffold(
      appBar: AppBar(title: Text(l10n.createGame)),
      body: FondoFarolero(
        intenso: true,
        child: SingleChildScrollView(
          padding: const EdgeInsets.fromLTRB(18, 18, 18, 28),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
            _CrearPartidaHeader(
              titulo: '?C?mo quieres jugar?',
              subtitulo: l10n.playersRange,
            ),
            const SizedBox(height: 12),
            if (!widget.bloquearModo) ...[
              // Modo de juego
              Card(
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(18, 18, 18, 28),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        l10n.gameMode,
                        style: Theme.of(context).textTheme.titleLarge,
                      ),
                      const SizedBox(height: 12),
                      SegmentedButton<bool>(
                        segments: [
                          ButtonSegment(
                            value: false,
                            label: Text(l10n.singleDevice),
                            icon: const Icon(Icons.phone_android),
                          ),
                          ButtonSegment(
                            value: true,
                            label: Text(l10n.multiDevice),
                            icon: const Icon(Icons.devices),
                          ),
                        ],
                        selected: {_modoMultimovil},
                        onSelectionChanged: (valor) {
                          setState(() {
                            _modoMultimovil = valor.first;
                            if (_numImpostores > _maxImpostores) {
                              _numImpostores = _maxImpostores;
                            }
                          });
                          _agregarPerfilLocalSiNecesario();
                        },
                      ),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 12),
            ] else ...[
              PanelFarolero(
                padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
                child: Row(
                  children: [
                    Icon(
                      _modoMultimovil ? Icons.devices : Icons.phone_android,
                      color: TemaApp.colorNaranja,
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Text(
                        _modoMultimovil
                            ? 'Partida multidispositivo'
                            : 'Partida en este dispositivo',
                        style: Theme.of(context).textTheme.titleMedium,
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 12),
            ],
            // Categoría
            Card(
              child: Padding(
                padding: const EdgeInsets.fromLTRB(18, 18, 18, 28),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      l10n.category,
                      style: Theme.of(context).textTheme.titleLarge,
                    ),
                    const SizedBox(height: 12),
                    SizedBox(
                      width: double.infinity,
                      child: DropdownButtonFormField<String>(
                        initialValue: _categoria,
                        decoration: const InputDecoration(
                          prefixIcon: Icon(Icons.category),
                        ),
                        items: categorias.map((c) {
                          return DropdownMenuItem(
                            value: c,
                            child: Text(
                              BancoPalabras.nombreBonitoCategoria(c, l10n),
                            ),
                          );
                        }).toList(),
                        onChanged: (v) => setState(() => _categoria = v!),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 12),

            if (!_modoMultimovil) ...[
              // Jugadores
              Card(
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(18, 18, 18, 28),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(
                          l10n.playersCount(_jugadores.length),
                          style: Theme.of(context).textTheme.titleLarge,
                        ),
                        Text(
                          l10n.playersRangeHint,
                          style: Theme.of(context).textTheme.bodyMedium,
                        ),
                      ],
                    ),
                    const SizedBox(height: 12),
                    Row(
                      children: [
                        Expanded(
                          child: TextField(
                            controller: _controladorNombre,
                            decoration: InputDecoration(
                              hintText: l10n.playerNameHint,
                              prefixIcon: const Icon(Icons.person_add),
                            ),
                            textCapitalization: TextCapitalization.words,
                            onSubmitted: (_) => _agregarJugador(),
                          ),
                        ),
                        const SizedBox(width: 8),
                        IconButton.filled(
                          onPressed: _agregarJugador,
                          icon: const Icon(Icons.add),
                        ),
                      ],
                    ),
                    const SizedBox(height: 8),
                    ..._jugadores.asMap().entries.map((e) {
                      final perfil = servicioPerfil.perfil;
                      final nombrePerfil = perfil.nombre.trim().isEmpty
                          ? 'Jugador'
                          : perfil.nombre.trim();
                      final inicialPerfil = nombrePerfil.isEmpty
                          ? '?'
                          : nombrePerfil.substring(0, 1).toUpperCase();
                      final esPerfilLocal =
                          e.key == 0 && e.value == nombrePerfil;
                      return ListTile(
                        leading: esPerfilLocal
                            ? AvatarFarolero(
                                texto: inicialPerfil,
                                assetPath: perfil.avatarAsset,
                                size: 54,
                              )
                            : CircleAvatar(
                                backgroundColor: TemaApp.colorTarjeta,
                                child: Text(
                                  '${e.key + 1}',
                                  style: const TextStyle(color: TemaApp.colorTexto),
                                ),
                              ),
                        title: Text(e.value),
                        subtitle: esPerfilLocal
                            ? const Text('Usuario principal del dispositivo')
                            : null,
                        trailing: esPerfilLocal
                            ? const Icon(Icons.lock, color: TemaApp.colorDorado)
                            : IconButton(
                                icon: const Icon(
                                  Icons.close,
                                  color: TemaApp.colorAcento,
                                ),
                                onPressed: () => _eliminarJugador(e.key),
                              ),
                        dense: true,
                      );
                    }),
                    ],
                  ),
                ),
              ),
              const SizedBox(height: 12),
            ],

            // Configuración de partida
            Card(
              child: Padding(
                padding: const EdgeInsets.fromLTRB(18, 18, 18, 28),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      l10n.configuration,
                      style: Theme.of(context).textTheme.titleLarge,
                    ),
                    const SizedBox(height: 12),

                    // Número de impostores
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(l10n.impostors),
                        Row(
                          children: [
                            IconButton(
                              onPressed: _numImpostores > 1
                                  ? () => setState(() => _numImpostores--)
                                  : null,
                              icon: const Icon(Icons.remove_circle_outline),
                            ),
                            Text(
                              '$_numImpostores',
                              style: Theme.of(context).textTheme.titleLarge,
                            ),
                            IconButton(
                              onPressed: _numImpostores < _maxImpostores
                                  ? () => setState(() => _numImpostores++)
                                  : null,
                              icon: const Icon(Icons.add_circle_outline),
                            ),
                          ],
                        ),
                      ],
                    ),

                    // Pista para impostor
                    SwitchListTile(
                      title: Text(l10n.impostorClue),
                      subtitle: Text(l10n.impostorClueDescription),
                      value: _pistaImpostor,
                      onChanged: (v) => setState(() => _pistaImpostor = v),
                      contentPadding: EdgeInsets.zero,
                    ),

                    // Temporizador
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(l10n.debateTime),
                        DropdownButton<int?>(
                          value: _tiempoDebate,
                          items: List.generate(
                            _opcionesTiempo.length,
                            (i) => DropdownMenuItem(
                              value: _opcionesTiempo[i],
                              child: Text(etiquetas[i]),
                            ),
                          ),
                          onChanged: (v) => setState(() => _tiempoDebate = v),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 24),

            // Botón iniciar
            BotonFarolero(
              texto: l10n.startGame,
              icono: Icons.play_arrow,
              onPressed: (_modoMultimovil || _jugadores.length >= 3)
                  ? _iniciarPartida
                  : null,
            ),
            const SizedBox(height: 16),
          ],
          ),
        ),
      ),
    );
  }
}

class _CrearPartidaHeader extends StatelessWidget {
  final String titulo;
  final String subtitulo;

  const _CrearPartidaHeader({
    required this.titulo,
    required this.subtitulo,
  });

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final ancho = constraints.maxWidth.clamp(320.0, 720.0).toDouble();
        return Center(
          child: ConstrainedBox(
            constraints: BoxConstraints(maxWidth: ancho),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                AspectRatio(
                  aspectRatio: 2,
                  child: Image.asset(
                    'assets/ui/generated/create_game/create_game_header_art.png',
                    fit: BoxFit.contain,
                    opacity: const AlwaysStoppedAnimation(0.96),
                  ),
                ),
                const SizedBox(height: 8),
                Text(
                  titulo,
                  textAlign: TextAlign.center,
                  style: Theme.of(context).textTheme.headlineSmall?.copyWith(
                        color: TemaApp.colorDorado,
                        fontWeight: FontWeight.w900,
                        shadows: [
                          Shadow(
                            color: TemaApp.colorNaranja.withValues(alpha: 0.55),
                            blurRadius: 16,
                          ),
                        ],
                      ),
                ),
                const SizedBox(height: 4),
                Text(
                  subtitulo,
                  textAlign: TextAlign.center,
                  style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                        color: TemaApp.colorTextoSecundario,
                      ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}
