import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';

import '../estado/estado_radio.dart';
import '../modelos/emisora.dart';
import '../servicios/servicio_audio.dart';
import '../servicios/servicio_timer.dart';
import '../tema/pluriwave_theme.dart';
import '../widgets/pluri_glass_surface.dart';
import '../widgets/pluri_wave_scaffold.dart';
import '../widgets/visualizador_audio.dart';

class PantallaReproductor extends StatefulWidget {
  final Emisora emisora;

  const PantallaReproductor({super.key, required this.emisora});

  static Future<void> abrir(BuildContext context, Emisora emisora) {
    return Navigator.push(
      context,
      PageRouteBuilder(
        pageBuilder: (_, animation, __) => PantallaReproductor(emisora: emisora),
        transitionsBuilder: (_, animation, __, child) => SlideTransition(
          position: Tween<Offset>(begin: const Offset(0, 1), end: Offset.zero)
              .animate(CurvedAnimation(parent: animation, curve: Curves.easeOutCubic)),
          child: child,
        ),
        transitionDuration: const Duration(milliseconds: 350),
      ),
    );
  }

  @override
  State<PantallaReproductor> createState() => _PantallaReproductorState();
}

class _PantallaReproductorState extends State<PantallaReproductor>
    with SingleTickerProviderStateMixin {
  late AnimationController _pulseController;

  @override
  void initState() {
    super.initState();
    _pulseController = AnimationController(vsync: this, duration: const Duration(seconds: 2));
    _iniciarReproduccion();
  }

  Future<void> _iniciarReproduccion() async {
    final estado = context.read<EstadoRadio>();
    if (estado.emisoraActual?.uuid != widget.emisora.uuid) {
      await estado.reproducir(widget.emisora);
    }
  }

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

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final tokens = context.pluriTokens;
    final estado = context.watch<EstadoRadio>();
    final emisoraActiva = estado.emisoraActual ?? widget.emisora;
    final esFavorito = estado.listaFavoritos.any((e) => e.uuid == emisoraActiva.uuid);

    return PluriWaveScaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        leading: IconButton(
          icon: const Icon(Icons.keyboard_arrow_down_rounded, size: 32),
          tooltip: 'Cerrar',
          onPressed: () => Navigator.pop(context),
        ),
        actions: [
          IconButton(
            icon: Icon(
              esFavorito ? Icons.favorite_rounded : Icons.favorite_outline_rounded,
              color: esFavorito ? theme.colorScheme.error : null,
            ),
            tooltip: esFavorito ? 'Quitar de favoritos' : 'Anadir a favoritos',
            onPressed: () async => estado.toggleFavorito(emisoraActiva),
          ),
        ],
      ),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20),
          child: Column(
            children: [
              const SizedBox(height: 8),
              _WaveHero(emisora: emisoraActiva, estadoStream: estado.estadoStream)
                  .animate()
                  .scale(begin: const Offset(0.86, 0.86), duration: 420.ms, curve: Curves.easeOutBack),
              const SizedBox(height: 18),
              Text(
                emisoraActiva.nombre,
                style: theme.textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.w700),
                textAlign: TextAlign.center,
                maxLines: 2,
                overflow: TextOverflow.ellipsis,
              ).animate().fadeIn(delay: 150.ms),
              const SizedBox(height: 10),
              _InfoChips(emisora: emisoraActiva).animate().fadeIn(delay: 200.ms).slideY(begin: 0.2),
              const SizedBox(height: 6),
              if (emisoraActiva.codec != null || emisoraActiva.bitrate != null)
                Text(
                  _codecInfo(emisoraActiva),
                  style: theme.textTheme.bodySmall?.copyWith(color: Colors.white.withValues(alpha: 0.72)),
                ).animate().fadeIn(delay: 250.ms),
              const SizedBox(height: 14),
              PluriGlassSurface(
                borderRadius: BorderRadius.circular(tokens.radiusLg),
                padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
                child: VisualizadorAudio(
                  estadoStream: estado.estadoStream,
                  barras: 26,
                  color: tokens.electricMagenta,
                  altura: 46,
                ),
              ).animate().fadeIn(delay: 280.ms),
              const Spacer(),
              _Controles(estado: estado, emisora: emisoraActiva)
                  .animate()
                  .fadeIn(delay: 300.ms)
                  .slideY(begin: 0.3),
              const SizedBox(height: 24),
              _TimerWidget(estado: estado).animate().fadeIn(delay: 400.ms),
              const SizedBox(height: 16),
            ],
          ),
        ),
      ),
    );
  }

  String _codecInfo(Emisora e) {
    final parts = <String>[];
    if (e.codec != null) parts.add(e.codec!.toUpperCase());
    if (e.bitrate != null && e.bitrate! > 0) parts.add('${e.bitrate} kbps');
    return parts.join(' · ');
  }
}

class _WaveHero extends StatelessWidget {
  final Emisora emisora;
  final Stream<EstadoReproduccion> estadoStream;

  const _WaveHero({required this.emisora, required this.estadoStream});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final t = context.pluriTokens;
    final size = MediaQuery.of(context).size.width * 0.62;

    return StreamBuilder<EstadoReproduccion>(
      stream: estadoStream,
      builder: (context, snapshot) {
        final reproduciendo = snapshot.data == EstadoReproduccion.reproduciendo;
        final cargando = snapshot.data == EstadoReproduccion.cargando;
        final hayError = snapshot.data == EstadoReproduccion.error;

        return SizedBox(
          width: size + 40,
          height: size + 40,
          child: Stack(
            alignment: Alignment.center,
            children: [
              Container(
                width: size + 34,
                height: size + 34,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  gradient: RadialGradient(
                    colors: [
                      t.electricMagenta.withValues(alpha: reproduciendo ? 0.35 : 0.18),
                      t.deepViolet.withValues(alpha: 0.0),
                    ],
                  ),
                ),
              ),
              Container(
                width: size + 12,
                height: size + 12,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  border: Border.all(color: Colors.white.withValues(alpha: 0.16)),
                ),
              ),
              PluriGlassSurface(
                borderRadius: BorderRadius.circular(size),
                padding: EdgeInsets.zero,
                child: SizedBox(
                  width: size,
                  height: size,
                  child: ClipOval(
                    child: Stack(
                      fit: StackFit.expand,
                      children: [
                        if (emisora.favicon != null && emisora.favicon!.isNotEmpty)
                          CachedNetworkImage(
                            imageUrl: emisora.favicon!,
                            fit: BoxFit.cover,
                            placeholder: (_, __) => _shimmer(theme),
                            errorWidget: (_, __, ___) => _iconoFallback(theme),
                          )
                        else
                          _iconoFallback(theme),
                        if (cargando)
                          Container(
                            color: Colors.black45,
                            child: const Center(child: CircularProgressIndicator(color: Colors.white)),
                          ),
                        if (hayError)
                          Container(
                            color: Colors.black54,
                            child: Center(
                              child: Icon(
                                Icons.wifi_off_rounded,
                                size: 56,
                                color: Colors.white.withValues(alpha: 0.85),
                              ),
                            ),
                          ),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      },
    );
  }

  Widget _shimmer(ThemeData theme) => Shimmer.fromColors(
    baseColor: theme.colorScheme.surfaceContainerHighest,
    highlightColor: theme.colorScheme.surface,
    child: Container(color: theme.colorScheme.surfaceContainerHighest),
  );

  Widget _iconoFallback(ThemeData theme) => Container(
    color: theme.colorScheme.primaryContainer,
    child: Icon(Icons.radio_rounded, size: 80, color: theme.colorScheme.onPrimaryContainer),
  );
}

class _InfoChips extends StatelessWidget {
  final Emisora emisora;
  const _InfoChips({required this.emisora});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final items = <String>[];
    if (emisora.pais != null) items.add(emisora.pais!);
    if (emisora.idioma != null) items.add(emisora.idioma!);
    if (items.isEmpty) return const SizedBox.shrink();

    return Wrap(
      spacing: 8,
      runSpacing: 6,
      alignment: WrapAlignment.center,
      children: items
          .map(
            (label) => Chip(
              label: Text(label),
              visualDensity: VisualDensity.compact,
              backgroundColor: theme.colorScheme.secondaryContainer.withValues(alpha: 0.8),
              labelStyle: TextStyle(color: theme.colorScheme.onSecondaryContainer, fontSize: 12),
              padding: EdgeInsets.zero,
            ),
          )
          .toList(),
    );
  }
}

class _Controles extends StatelessWidget {
  final EstadoRadio estado;
  final Emisora emisora;

  const _Controles({required this.estado, required this.emisora});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return StreamBuilder<EstadoReproduccion>(
      stream: estado.estadoStream,
      builder: (context, snapshot) {
        final s = snapshot.data ?? EstadoReproduccion.detenido;
        final reproduciendo = s == EstadoReproduccion.reproduciendo;
        final cargando = s == EstadoReproduccion.cargando;
        final hayError = s == EstadoReproduccion.error;

        if (hayError) {
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(Icons.error_outline_rounded, size: 40, color: theme.colorScheme.error),
              const SizedBox(height: 8),
              Text(
                'No se puede reproducir esta radio',
                style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.error),
                textAlign: TextAlign.center,
              ),
              const SizedBox(height: 12),
              FilledButton.tonalIcon(
                icon: const Icon(Icons.refresh_rounded, size: 18),
                label: const Text('Reintentar'),
                onPressed: () => estado.reproducir(emisora),
              ),
            ],
          );
        }

        return PluriGlassSurface(
          borderRadius: BorderRadius.circular(28),
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Semantics(
                button: true,
                label: 'Detener reproduccion',
                child: IconButton(
                  icon: const Icon(Icons.stop_rounded),
                  iconSize: 34,
                  constraints: const BoxConstraints(minWidth: 56, minHeight: 56),
                  color: Colors.white.withValues(alpha: 0.78),
                  tooltip: 'Detener',
                  onPressed: cargando ? null : () => estado.audio.detener(),
                ),
              ),
              const SizedBox(width: 16),
              AnimatedContainer(
                duration: const Duration(milliseconds: 200),
                width: 72,
                height: 72,
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: theme.colorScheme.primary,
                  boxShadow: [
                    BoxShadow(
                      color: theme.colorScheme.primary.withValues(alpha: 0.35),
                      blurRadius: reproduciendo ? 16 : 6,
                      spreadRadius: reproduciendo ? 4 : 0,
                    ),
                  ],
                ),
                child: Material(
                  color: Colors.transparent,
                  shape: const CircleBorder(),
                  child: InkWell(
                    customBorder: const CircleBorder(),
                    radius: 40,
                    onTap: cargando
                        ? null
                        : () {
                            if (reproduciendo || s == EstadoReproduccion.pausado) {
                              estado.togglePlay();
                            } else {
                              estado.reproducir(emisora);
                            }
                          },
                    child: Semantics(
                      button: true,
                      label: reproduciendo ? 'Pausar reproduccion' : 'Iniciar reproduccion',
                      child: Center(
                        child: cargando
                            ? const SizedBox(
                                width: 28,
                                height: 28,
                                child: CircularProgressIndicator(strokeWidth: 2.5, color: Colors.white),
                              )
                            : Icon(
                                reproduciendo ? Icons.pause_rounded : Icons.play_arrow_rounded,
                                size: 40,
                                color: theme.colorScheme.onPrimary,
                              ),
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 16),
              Semantics(
                label: reproduciendo ? 'En vivo' : 'No esta reproduciendo',
                child: Icon(
                  Icons.fiber_manual_record_rounded,
                  size: 32,
                  color: reproduciendo ? theme.colorScheme.error : theme.colorScheme.surfaceContainerHighest,
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

class _TimerWidget extends StatelessWidget {
  final EstadoRadio estado;
  const _TimerWidget({required this.estado});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    if (!estado.timer.activo) {
      return TextButton.icon(
        icon: const Icon(Icons.bedtime_outlined, size: 18),
        label: const Text('Timer de sueno'),
        onPressed: () => _mostrarTimerDialog(context),
      );
    }

    return StreamBuilder<Duration>(
      stream: estado.timer.tiempoRestanteStream,
      builder: (context, snap) {
        final t = snap.data ?? Duration.zero;
        final m = t.inMinutes.remainder(60).toString().padLeft(2, '0');
        final s = t.inSeconds.remainder(60).toString().padLeft(2, '0');
        final label = t.inHours > 0 ? '${t.inHours}h ${m}m' : '${m}m ${s}s';

        return Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.bedtime_rounded, size: 16, color: theme.colorScheme.primary),
            const SizedBox(width: 6),
            Text(label, style: theme.textTheme.bodyMedium),
            const SizedBox(width: 8),
            TextButton(
              onPressed: () => estado.cancelarTimer(),
              style: TextButton.styleFrom(
                visualDensity: VisualDensity.compact,
                padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
              ),
              child: const Text('Cancelar'),
            ),
          ],
        );
      },
    );
  }

  void _mostrarTimerDialog(BuildContext context) {
    showModalBottomSheet(
      context: context,
      builder: (ctx) => SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Timer de sueno', style: Theme.of(ctx).textTheme.titleLarge),
              const SizedBox(height: 16),
              Wrap(
                spacing: 8,
                children: opcionesTimer
                    .map(
                      (min) => ActionChip(
                        label: Text('$min min'),
                        onPressed: () {
                          estado.iniciarTimer(min);
                          Navigator.pop(ctx);
                        },
                      ),
                    )
                    .toList(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
