import 'dart:async';
import 'dart:math';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';

import '../../app/theme.dart';
import '../../providers/score_provider.dart';
import '../../providers/session_provider.dart';
import '../../shared/api_client.dart';
import '../../shared/models/match.dart';
import '../../shared/models/score_state.dart';
import '../../shared/models/stream_session.dart';
import '../../shared/websocket_service.dart';
import '../../shared/regia_share.dart';
import '../../shared/widgets/metric_card.dart';
import '../../shared/widgets/primary_cta.dart';
import '../../shared/widgets/screen_insets.dart';

class StepNetworkTest extends ConsumerStatefulWidget {
  const StepNetworkTest({
    super.key,
    required this.match,
    required this.onBack,
  });

  final MatchModel match;
  final VoidCallback onBack;

  @override
  ConsumerState<StepNetworkTest> createState() => _StepNetworkTestState();
}

class _StepNetworkTestState extends ConsumerState<StepNetworkTest> {
  bool _testing = false;
  bool _ready = false;
  double _downloadMbps = 0;
  double _uploadMbps = 0;
  int _latencyMs = 0;
  String _networkType = '—';
  bool _starting = false;

  Future<void> _runTest() async {
    setState(() {
      _testing = true;
      _ready = false;
    });

    final connectivity = await Connectivity().checkConnectivity();
    final networkLabel = _connectivityLabel(connectivity);

    // Simulazione test rete locale (sostituibile con speed test reale).
    await Future<void>.delayed(const Duration(seconds: 2));
    final rng = Random();
    final download = 8 + rng.nextDouble() * 12;
    final upload = 2 + rng.nextDouble() * 4;
    final latency = 20 + rng.nextInt(80);

    final session = ref.read(sessionProvider).session;
    NetworkTestResult? testResult;
    if (session != null) {
      try {
        final client = ref.read(apiClientProvider);
        testResult = await client.networkTest(
          sessionId: session.id,
          downloadMbps: download,
          uploadMbps: upload,
          latencyMs: latency,
          networkType: networkLabel,
        );
      } catch (_) {
        testResult = null;
      }
    }

    if (mounted) {
      setState(() {
        _testing = false;
        _downloadMbps = download;
        _uploadMbps = upload;
        _latencyMs = latency;
        _networkType = networkLabel;
        _ready = testResult?.ready ?? upload >= 2.0;
      });
    }
  }

  String _connectivityLabel(List<ConnectivityResult> results) {
    if (results.contains(ConnectivityResult.wifi)) return 'WiFi';
    if (results.contains(ConnectivityResult.mobile)) return '4G';
    if (results.contains(ConnectivityResult.ethernet)) return 'Ethernet';
    return 'Sconosciuto';
  }

  Future<void> _startLive() async {
    final sessionState = ref.read(sessionProvider);
    final session = sessionState.session;
    if (session == null) return;

    setState(() => _starting = true);
    try {
      final client = ref.read(apiClientProvider);
      final started = await client.startSession(session.id);
      ref.read(sessionProvider.notifier).setSession(started, match: widget.match);

      if (started.score != null) {
        ref.read(scoreProvider.notifier).reset(started.score!);
      } else {
        ref.read(scoreProvider.notifier).reset(const ScoreState());
      }

      if (!mounted) return;
      context.go('/session/${started.id}/camera');

      try {
        final ws = ref.read(websocketServiceProvider);
        await ws.connect(sessionId: started.id, deviceRole: 'camera');
      } catch (e) {
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Diretta avviata ma sync limitata: $e')),
          );
        }
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Errore avvio diretta: $e')),
        );
      }
    } finally {
      if (mounted) setState(() => _starting = false);
    }
  }

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

    return SingleChildScrollView(
      padding: ScreenInsets.contentPadding(context, horizontal: 20, vertical: 12),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text('Test rete', style: theme.textTheme.titleLarge),
          const SizedBox(height: 8),
          Text(
            'Verifica che la connessione regga l\'upload della diretta.',
            style: theme.textTheme.bodyMedium,
          ),
          const SizedBox(height: 24),
          Row(
            children: [
              MetricCard(
                label: 'Download',
                value: _testing ? '...' : '${_downloadMbps.toStringAsFixed(1)} Mbps',
                icon: Icons.download,
              ),
              const SizedBox(width: 8),
              MetricCard(
                label: 'Upload',
                value: _testing ? '...' : '${_uploadMbps.toStringAsFixed(1)} Mbps',
                icon: Icons.upload,
                highlight: _ready,
              ),
              const SizedBox(width: 8),
              MetricCard(
                label: 'Latenza',
                value: _testing ? '...' : '${_latencyMs} ms',
                icon: Icons.speed,
              ),
            ],
          ),
          const SizedBox(height: 12),
          SizedBox(
            width: double.infinity,
            child: MetricCard(
              label: 'Tipo rete',
              value: _networkType,
              icon: Icons.signal_cellular_alt,
              expand: false,
            ),
          ),
          const SizedBox(height: 20),
          if (_ready) ...[
            Container(
              padding: const EdgeInsets.all(14),
              decoration: BoxDecoration(
                color: AppTheme.successGreen.withValues(alpha: 0.15),
                borderRadius: BorderRadius.circular(10),
                border: Border.all(color: AppTheme.successGreen.withValues(alpha: 0.4)),
              ),
              child: Text(
                'PRONTO PER ANDARE IN DIRETTA',
                style: theme.textTheme.titleMedium?.copyWith(
                  color: AppTheme.successGreen,
                ),
                textAlign: TextAlign.center,
              ),
            ),
            if (ref.read(sessionProvider).session?.watchPageUrl != null) ...[
              const SizedBox(height: 12),
              Container(
                padding: const EdgeInsets.all(14),
                decoration: BoxDecoration(
                  color: AppTheme.surfaceElevated,
                  borderRadius: BorderRadius.circular(10),
                ),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Text(
                      'Link per gli spettatori',
                      style: theme.textTheme.titleSmall,
                    ),
                    const SizedBox(height: 8),
                    SelectableText(
                      ref.read(sessionProvider).session!.watchPageUrl!,
                      style: theme.textTheme.bodySmall,
                    ),
                    const SizedBox(height: 8),
                    OutlinedButton.icon(
                      onPressed: () {
                        final url = ref.read(sessionProvider).session!.watchPageUrl!;
                        Clipboard.setData(ClipboardData(text: url));
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(content: Text('Link copiato')),
                        );
                      },
                      icon: const Icon(Icons.link, size: 18),
                      label: const Text('COPIA LINK DIRETTA'),
                    ),
                  ],
                ),
              ),
            ],
          ],
          const SizedBox(height: 16),
          Container(
            padding: const EdgeInsets.all(14),
            decoration: BoxDecoration(
              color: AppTheme.surfaceElevated,
              borderRadius: BorderRadius.circular(10),
            ),
            child: Text(
              'In caso di disconnessione, lo stream resta attivo con slate per massimo 5 minuti mentre il telefono riconnette.',
              style: theme.textTheme.bodyMedium,
            ),
          ),
          const SizedBox(height: 16),
          OutlinedButton.icon(
            onPressed: ref.read(sessionProvider).session == null
                ? null
                : () => shareRegiaLink(
                      context,
                      ref,
                      sessionId: ref.read(sessionProvider).session!.id,
                      shareSubject:
                          'Regia — ${widget.match.teamName} vs ${widget.match.opponentName}',
                    ),
            icon: const Icon(Icons.share),
            label: const Text('Condividi link regia (punteggio)'),
          ),
          const SizedBox(height: 24),
          OutlinedButton(
            onPressed: _testing ? null : _runTest,
            child: Text(_testing ? 'TEST IN CORSO...' : 'AVVIA TEST RETE'),
          ),
          const SizedBox(height: 32),
          Row(
            children: [
              Expanded(
                child: OutlinedButton(
                  onPressed: _starting ? null : widget.onBack,
                  child: const Text('Indietro'),
                ),
              ),
              const SizedBox(width: 12),
              Expanded(
                flex: 2,
                child: PrimaryCta(
                  label: 'INIZIA >',
                  loading: _starting,
                  onPressed: _ready ? _startLive : null,
                  icon: Icons.play_arrow,
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
