// P1 debug stats overlay widget.
//
// Shows a compact, auto-refreshing panel with the key audio processing
// metrics from [BridgeAudioProcessingStats]. Intended for internal
// debug builds only — wrap with a kDebugMode guard at the call site.
//
// Usage:
//   if (kDebugMode) const AudioDebugStatsPanel(),

import 'dart:async';

import 'package:flutter/material.dart';

import '../src/rust/api.dart';

/// Compact debug panel that polls [audioProcessingStats] every 500 ms
/// and renders the key metrics in a monospace overlay.
///
/// Designed to be placed in a [Stack] over the main UI during
/// development. It is transparent to hit-testing so it does not
/// interfere with taps.
class AudioDebugStatsPanel extends StatefulWidget {
  const AudioDebugStatsPanel({super.key});

  @override
  State<AudioDebugStatsPanel> createState() => _AudioDebugStatsPanelState();
}

class _AudioDebugStatsPanelState extends State<AudioDebugStatsPanel> {
  BridgeAudioProcessingStats? _stats;
  Timer? _timer;
  String? _error;

  @override
  void initState() {
    super.initState();
    _poll();
    _timer = Timer.periodic(const Duration(milliseconds: 500), (_) => _poll());
  }

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

  Future<void> _poll() async {
    try {
      final stats = await audioProcessingStats();
      if (mounted) {
        setState(() {
          _stats = stats;
          _error = null;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() => _error = e.toString());
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return IgnorePointer(
      child: Align(
        alignment: Alignment.topRight,
        child: SafeArea(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: _buildPanel(),
          ),
        ),
      ),
    );
  }

  Widget _buildPanel() {
    if (_error != null) {
      return _PanelBox(
        child: Text(
          'audio stats error:\n$_error',
          style: _monoStyle(Colors.red),
        ),
      );
    }

    final s = _stats;
    if (s == null) {
      return _PanelBox(
        child: Text('audio stats: loading…', style: _monoStyle(Colors.grey)),
      );
    }

    final vadColor = s.vadActive ? Colors.greenAccent : Colors.grey;
    final txColor = s.transmitting ? Colors.redAccent : Colors.grey;
    final xruns = s.callbackXruns + s.inputOverruns + s.outputUnderruns;

    return _PanelBox(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          _row('route', _routeLabel(s.audioRoute), Colors.white),
          _row('backend', _backendLabel(s.processingBackend), Colors.white),
          _row(
            'vpio',
            s.platformVoiceProcessingEnabled ? 'on' : 'off',
            Colors.white,
          ),
          if (s.processingBackend == BridgeAudioBackend.sonora)
            _row('sonora', s.sonoraEnabled ? 'on' : 'off', Colors.white),
          const SizedBox(height: 4),
          _row(
            'mic in',
            '${s.inputDbfs.toStringAsFixed(1)} dBFS',
            Colors.white,
          ),
          _row(
            'mic out',
            '${s.processedDbfs.toStringAsFixed(1)} dBFS',
            Colors.white,
          ),
          _row(
            'render',
            '${s.renderDbfs.toStringAsFixed(1)} dBFS',
            Colors.white,
          ),
          const SizedBox(height: 4),
          _row(
            'vad',
            '${(s.vadProbability * 100).toStringAsFixed(0)}% '
                '${s.vadActive ? "OPEN" : "closed"}',
            vadColor,
          ),
          _row('vad backend', _vadBackendLabel(s.vadBackend), Colors.white),
          if (s.vadFallbackActive)
            _row('vad fallback', 'ACTIVE', Colors.orange),
          const SizedBox(height: 4),
          _row('tx', s.transmitting ? 'TRANSMITTING' : 'idle', txColor),
          _row('sr', '${s.actualSampleRateHz} Hz', Colors.white),
          _row('buf', '${s.actualIoBufferFrames} frames', Colors.white),
          if (xruns > BigInt.zero)
            _row('xruns', xruns.toString(), Colors.orange),
          if (s.clippedSamples > BigInt.zero)
            _row('clipped', s.clippedSamples.toString(), Colors.orange),
        ],
      ),
    );
  }

  Widget _row(String label, String value, Color valueColor) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text('$label: ', style: _monoStyle(Colors.grey.shade400)),
        Text(value, style: _monoStyle(valueColor)),
      ],
    );
  }

  TextStyle _monoStyle(Color color) => TextStyle(
    fontFamily: 'monospace',
    fontSize: 10,
    color: color,
    height: 1.4,
  );

  String _routeLabel(BridgeAudioRoute route) => switch (route) {
    BridgeAudioRoute.speaker => 'speaker',
    BridgeAudioRoute.earpiece => 'earpiece',
    BridgeAudioRoute.wiredHeadset => 'wired',
    BridgeAudioRoute.bluetoothHfp => 'bt-hfp',
    BridgeAudioRoute.bluetoothA2Dp => 'bt-a2dp',
    BridgeAudioRoute.unknown => 'unknown',
  };

  String _backendLabel(BridgeAudioBackend backend) => switch (backend) {
    BridgeAudioBackend.platformVoiceProcessing => 'vpio',
    BridgeAudioBackend.sonora => 'sonora',
    BridgeAudioBackend.noop => 'noop',
    BridgeAudioBackend.webrtcApm => 'webrtc-apm',
  };

  String _vadBackendLabel(BridgeVadBackend backend) => switch (backend) {
    BridgeVadBackend.webrtcVad => 'webrtc',
    BridgeVadBackend.sileroOnnx => 'silero',
    BridgeVadBackend.energyDebug => 'energy',
    BridgeVadBackend.disabled => 'off',
  };
}

/// Semi-transparent dark box for the debug panel.
class _PanelBox extends StatelessWidget {
  const _PanelBox({required this.child});
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
      decoration: BoxDecoration(
        color: Colors.black.withValues(alpha: 0.72),
        borderRadius: BorderRadius.circular(6),
      ),
      child: child,
    );
  }
}
