import 'dart:async';
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

import '../models/school.dart';
import '../services/vanguard_api.dart';
import 'home_page.dart';
import 'lessons_page.dart';
import 'select_school_page.dart';
import 'login_page.dart';
import '../widgets/app_drawer.dart';
import '../widgets/app_bottom_nav.dart';
import '../widgets/yogibook_background.dart';

class MeditationPage extends StatefulWidget {
  final String token;
  final School school;
  final String? userFirstName;

  const MeditationPage({
    super.key,
    required this.token,
    required this.school,
    this.userFirstName,
  });

  @override
  State<MeditationPage> createState() => _MeditationPageState();
}

class _MeditationPageState extends State<MeditationPage>
    with TickerProviderStateMixin {
  static const Color kBg = Color(0xFFF6F6FB);
  static const Color kGreen = Color(0xFF10B981);

  // ======= AUDIO =======
  final AudioPlayer _bgPlayer = AudioPlayer();
  bool _musicMuted = false;
  bool _musicStarted = false;
  static const double _musicVolume = 0.35;

  // Metti il tuo file qui (consigliato: asset locale)
  // 1) Metti il file in: assets/audio/meditation.mp3
  // 2) Aggiungi in pubspec.yaml:
  //    assets:
  //      - assets/audio/meditation.mp3
  static const String _musicAssetPath = 'audio/meditation.mp3';

  // ======= TIMER =======
  static const int totalSeconds = 10 * 60; // 10 min
  int remainingSeconds = totalSeconds;
  bool running = false;

  // ======= SQUARE BREATHING 4-4-4-4 =======
  static const int inhaleSec = 4;
  static const int hold1Sec = 4;
  static const int exhaleSec = 4;
  static const int hold2Sec = 4;
  static const int cycleSec = inhaleSec + hold1Sec + exhaleSec + hold2Sec;

  Timer? _timer;

  // UI anims
  late final AnimationController _pulseCtrl;
  late final AnimationController _squareCtrl;

  int bottomIndex = 3; // Meditazione

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

    _pulseCtrl = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1800),
    )..repeat(reverse: true);

    _squareCtrl = AnimationController(
      vsync: this,
      duration: const Duration(seconds: cycleSec),
    );

    // audio options
    _bgPlayer.setReleaseMode(ReleaseMode.loop);
    _bgPlayer.setVolume(_musicMuted ? 0.0 : _musicVolume);
  }

  @override
  void dispose() {
    _timer?.cancel();
    _pulseCtrl.dispose();
    _squareCtrl.dispose();
    _bgPlayer.dispose();
    super.dispose();
  }

  // ======= AUDIO HELPERS =======
  Future<void> _ensureMusicStarted() async {
    if (_musicStarted) return;

    try {
      // audioplayers: AssetSource usa path relativo alla cartella assets/
      await _bgPlayer.play(
        AssetSource(_musicAssetPath),
        volume: _musicMuted ? 0.0 : _musicVolume,
      );
      _musicStarted = true;
    } catch (_) {
      // Se manca l'asset o errore audio, non blocchiamo la pagina.
      // (Puoi loggare se vuoi)
    }
  }

  Future<void> _applyMusicVolume() async {
    try {
      await _bgPlayer.setVolume(_musicMuted ? 0.0 : _musicVolume);
    } catch (_) {}
  }

  Future<void> _toggleMute() async {
    setState(() => _musicMuted = !_musicMuted);

    // se l’audio non è mai partito, lo facciamo partire al primo toggle o al primo start
    if (!_musicStarted) {
      await _ensureMusicStarted();
    } else {
      await _applyMusicVolume();
    }
  }

  Future<void> _stopMusic() async {
    try {
      await _bgPlayer.stop();
    } catch (_) {}
  }

  // ======= SESSION CONTROLS =======
  Future<void> _start() async {
    if (running) return;

    // start music on user action (safer for iOS)
    await _ensureMusicStarted();
    await _applyMusicVolume();

    setState(() => running = true);

    // start square animation
    _squareCtrl.repeat();

    _timer ??= Timer.periodic(const Duration(seconds: 1), (_) {
      if (!mounted) return;

      if (remainingSeconds <= 0) {
        _pause();
        return;
      }

      setState(() => remainingSeconds -= 1);
    });
  }

  void _pause() {
    setState(() => running = false);
    _timer?.cancel();
    _timer = null;

    _squareCtrl.stop();
    // musica: la lasciamo andare ma mutabile; se vuoi che si fermi in pausa:
    // _bgPlayer.pause();
  }

  void _reset() {
    _pause();
    setState(() => remainingSeconds = totalSeconds);
    _squareCtrl.reset();
  }

  // ======= LOGOUT =======
  Future<void> _logout() async {
    final ok = await showDialog<bool>(
      context: context,
      builder: (_) => AlertDialog(
        title: const Text('Conferma logout'),
        content: const Text('Vuoi uscire dal tuo account?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Annulla'),
          ),
          ElevatedButton(
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Logout'),
          ),
        ],
      ),
    );

    if (ok != true) return;

    // chiude drawer (qui siamo nel drawer)
    Navigator.of(context).pop();

    // stop music
    await _stopMusic();

    try {
      await VanguardApi.logout(token: widget.token);
    } catch (_) {
      // anche se fallisce lato server, usciamo lo stesso
    }

    if (!mounted) return;

    Navigator.of(context).pushAndRemoveUntil(
      MaterialPageRoute(builder: (_) => const LoginPage()),
      (route) => false,
    );
  }

  // ======= UI HELPERS =======
  String get _breathLabel {
    final t = (_squareCtrl.value * cycleSec) % cycleSec;
    if (t < inhaleSec) return 'Inspira';
    if (t < inhaleSec + hold1Sec) return 'Trattieni';
    if (t < inhaleSec + hold1Sec + exhaleSec) return 'Espira';
    return 'Trattieni';
  }

  double get _progress {
    final done = totalSeconds - remainingSeconds;
    return done <= 0 ? 0 : (done / totalSeconds).clamp(0.0, 1.0);
  }

  String _mmss(int sec) {
    final m = (sec ~/ 60).toString().padLeft(2, '0');
    final s = (sec % 60).toString().padLeft(2, '0');
    return '$m:$s';
  }

  String get _name => (widget.userFirstName ?? '').trim();
  String get _avatarLetter => _name.isNotEmpty ? _name[0].toUpperCase() : 'U';

  Future<void> _goTo(Widget page) async {
    _pause();
    await _stopMusic();
    if (!mounted) return;
    Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => page));
  }

  void _handleBottomNav(int i) {
    if (i == bottomIndex) return;
    setState(() => bottomIndex = i);

    if (i == 0) {
      _goTo(
        HomePage(
          token: widget.token,
          school: widget.school,
          userFirstName: widget.userFirstName,
        ),
      );
      return;
    }

    if (i == 1) {
      _goTo(
        LessonsPage(
          token: widget.token,
          school: widget.school,
          userFirstName: widget.userFirstName,
        ),
      );
      return;
    }

    if (i == 2) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('TODO: vai ad Account')));
      return;
    }

    // i == 3 => già qui
  }

  @override
  Widget build(BuildContext context) {
    final bubbleScale = Tween<double>(
      begin: 0.96,
      end: 1.06,
    ).animate(CurvedAnimation(parent: _pulseCtrl, curve: Curves.easeInOut));

    return Scaffold(
      drawer: AppDrawer(
        token: widget.token,
        school: widget.school,
        userFirstName: widget.userFirstName,
      ),

      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        centerTitle: true,
        title: const Text(
          'Meditazione',
          style: TextStyle(fontWeight: FontWeight.w800, fontSize: 18),
        ),
        actions: [
          IconButton(
            tooltip: _musicMuted ? 'Audio OFF' : 'Audio ON',
            onPressed: _toggleMute,
            icon: Icon(
              _musicMuted ? Icons.volume_off_rounded : Icons.volume_up_rounded,
              color: Colors.black87,
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(right: 12),
            child: CircleAvatar(
              radius: 16,
              backgroundColor: kGreen,
              child: Text(
                _avatarLetter,
                style: const TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w900,
                  fontSize: 12,
                ),
              ),
            ),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        backgroundColor: Colors.white,
        selectedItemColor: kGreen,
        unselectedItemColor: Colors.black54,
        currentIndex: bottomIndex,
        onTap: _handleBottomNav,
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home_rounded),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.event_note_rounded),
            label: 'Lezioni',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person_rounded),
            label: 'Account',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.self_improvement_rounded),
            label: 'Meditazione',
          ),
        ],
      ),
      body: YogibookBackground(
        child: SafeArea(
          top: false,
          child: Padding(
            padding: const EdgeInsets.fromLTRB(16, 10, 16, 16),
            child: Column(
              children: [
                // Top card with progress
                Container(
                  width: double.infinity,
                  padding: const EdgeInsets.fromLTRB(14, 12, 14, 14),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(18),
                    boxShadow: const [
                      BoxShadow(
                        blurRadius: 18,
                        color: Color(0x12000000),
                        offset: Offset(0, 10),
                      ),
                    ],
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      const Text(
                        'Respiro consapevole',
                        style: TextStyle(
                          fontSize: 14,
                          fontWeight: FontWeight.w900,
                        ),
                      ),
                      const SizedBox(height: 8),
                      ClipRRect(
                        borderRadius: BorderRadius.circular(999),
                        child: LinearProgressIndicator(
                          minHeight: 8,
                          value: _progress,
                          backgroundColor: const Color(0xFFE9E9EF),
                          valueColor: const AlwaysStoppedAnimation(
                            Color(0xFFF59E0B),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),

                const SizedBox(height: 20),

                // Square + countdown
                Expanded(
                  child: SingleChildScrollView(
                    child: Padding(
                      padding: const EdgeInsets.only(top: 8, bottom: 8),
                      child: Center(
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            AnimatedBuilder(
                              animation: Listenable.merge([
                                _squareCtrl,
                                bubbleScale,
                              ]),
                              builder: (_, __) {
                                final scale = bubbleScale.value;

                                return Transform.scale(
                                  scale: scale,
                                  child: CustomPaint(
                                    painter: _SquareBreathPainter(
                                      t: _squareCtrl.value,
                                      color: kGreen,
                                    ),
                                    child: SizedBox(
                                      width: 240,
                                      height: 240,
                                      child: Center(
                                        child: Text(
                                          _breathLabel,
                                          style: const TextStyle(
                                            color: Colors.white,
                                            fontWeight: FontWeight.w800,
                                            fontSize: 18,
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                );
                              },
                            ),

                            const SizedBox(height: 24),

                            Text(
                              _mmss(remainingSeconds),
                              style: const TextStyle(
                                fontSize: 44,
                                fontWeight: FontWeight.w900,
                                color: Color(0xFF1F1F1F),
                              ),
                            ),
                            const SizedBox(height: 6),
                            const Text(
                              'Tempo rimanente',
                              style: TextStyle(
                                color: Colors.black45,
                                fontWeight: FontWeight.w600,
                              ),
                            ),

                            const SizedBox(height: 18),

                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                SizedBox(
                                  height: 44,
                                  child: ElevatedButton.icon(
                                    onPressed: running ? _pause : _start,
                                    style: ElevatedButton.styleFrom(
                                      backgroundColor: kGreen,
                                      shape: RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(14),
                                      ),
                                    ),
                                    icon: Icon(
                                      running ? Icons.pause : Icons.play_arrow,
                                    ),
                                    label: Text(running ? 'Pausa' : 'Avvia'),
                                  ),
                                ),
                                const SizedBox(width: 12),
                                SizedBox(
                                  height: 44,
                                  child: OutlinedButton(
                                    onPressed: _reset,
                                    style: OutlinedButton.styleFrom(
                                      side: const BorderSide(
                                        color: kGreen,
                                        width: 2,
                                      ),
                                      shape: RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(14),
                                      ),
                                    ),
                                    child: const Text(
                                      'Reset',
                                      style: TextStyle(
                                        color: Colors.black87,
                                        fontWeight: FontWeight.w800,
                                      ),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),

                SizedBox(
                  width: double.infinity,
                  height: 52,
                  child: ElevatedButton(
                    onPressed: () async {
                      _pause();
                      await _stopMusic();
                      if (!mounted) return;

                      Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                          builder: (_) => HomePage(
                            token: widget.token,
                            school: widget.school,
                            userFirstName: widget.userFirstName,
                          ),
                        ),
                      );
                    },
                    style: ElevatedButton.styleFrom(
                      backgroundColor: kGreen,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(16),
                      ),
                    ),
                    child: const Text(
                      'TERMINA SESSIONE',
                      style: TextStyle(fontWeight: FontWeight.w900),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _SquareBreathPainter extends CustomPainter {
  final double t; // 0..1
  final Color color;

  _SquareBreathPainter({required this.t, required this.color});

  @override
  void paint(Canvas canvas, Size size) {
    final pad = 18.0;
    final rect = Rect.fromLTWH(
      pad,
      pad,
      size.width - pad * 2,
      size.height - pad * 2,
    );
    final rrect = RRect.fromRectAndRadius(rect, const Radius.circular(22));

    // background layers
    final bg1 = Paint()
      ..color = color.withOpacity(0.20)
      ..style = PaintingStyle.fill;
    final bg2 = Paint()
      ..color = color.withOpacity(0.28)
      ..style = PaintingStyle.fill;
    final bg3 = Paint()
      ..color = color.withOpacity(1.0)
      ..style = PaintingStyle.fill;

    canvas.save();
    canvas.translate(2, 4);
    canvas.drawRRect(rrect, bg1);
    canvas.restore();

    canvas.save();
    canvas.translate(-2, -2);
    canvas.drawRRect(rrect, bg2);
    canvas.restore();

    canvas.drawRRect(rrect, bg3);

    // border
    final border = Paint()
      ..color = Colors.white.withOpacity(0.25)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.2;
    canvas.drawRRect(rrect, border);

    // dot
    final p = _dotPositionOnSquare(rect, t);

    final dotOuter = Paint()..color = Colors.white.withOpacity(0.95);
    final dotInner = Paint()..color = color.withOpacity(1.0);

    canvas.drawCircle(p, 9.5, dotOuter);
    canvas.drawCircle(p, 6.2, dotInner);
  }

  Offset _dotPositionOnSquare(Rect rect, double t01) {
    const inhale = _MeditationPageState.inhaleSec;
    const hold1 = _MeditationPageState.hold1Sec;
    const exhale = _MeditationPageState.exhaleSec;
    const hold2 = _MeditationPageState.hold2Sec;
    const cycle = _MeditationPageState.cycleSec;

    final x0 = rect.left;
    final x1 = rect.right;
    final y0 = rect.bottom;
    final y1 = rect.top;

    final tt = (t01 * cycle) % cycle;
    double u;

    // bottom-left -> up (Inspira)
    if (tt < inhale) {
      u = tt / inhale;
      return Offset(x0, _lerp(y0, y1, u));
    }

    // top-left -> right (Trattieni)
    if (tt < inhale + hold1) {
      u = (tt - inhale) / hold1;
      return Offset(_lerp(x0, x1, u), y1);
    }

    // top-right -> down (Espira)
    if (tt < inhale + hold1 + exhale) {
      u = (tt - inhale - hold1) / exhale;
      return Offset(x1, _lerp(y1, y0, u));
    }

    // bottom-right -> left (Trattieni)
    u = (tt - inhale - hold1 - exhale) / hold2;
    return Offset(_lerp(x1, x0, u), y0);
  }

  double _lerp(double a, double b, double t) => a + (b - a) * t;

  @override
  bool shouldRepaint(covariant _SquareBreathPainter oldDelegate) {
    return oldDelegate.t != t || oldDelegate.color != color;
  }
}
