import 'dart:math' show max;

import 'package:flutter/material.dart';

/// Shared compact level meter used by voice surfaces.
///
/// When [level] is null (no stats available yet), falls back to [active]
/// for a binary indicator. When [level] is provided it is interpreted as
/// dBFS and mapped to a 0–1 fill fraction via [dbfsToFraction] (floors
/// at -60 dBFS).
class VoiceLevelMeter extends StatefulWidget {
  const VoiceLevelMeter({super.key, this.active = false, this.level});

  /// Binary fallback when no dBFS value is available.
  final bool active;

  /// Real input level in dBFS (-120 = silence, 0 = clipping).
  /// Null means stats are not yet available; [active] is used instead.
  final double? level;

  /// Map dBFS [-60, 0] → [0.0, 1.0].
  static double dbfsToFraction(double dbfs) {
    const floor = -60.0;
    if (dbfs <= floor) return 0.0;
    if (dbfs >= 0.0) return 1.0;
    return (dbfs - floor) / -floor;
  }

  @override
  State<VoiceLevelMeter> createState() => _VoiceLevelMeterState();
}

class _VoiceLevelMeterState extends State<VoiceLevelMeter> {
  double _previousFill = 0.0;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final double fill;
    final Color color;
    if (widget.level != null) {
      fill = VoiceLevelMeter.dbfsToFraction(widget.level!);
      color = fill > 0.0
          ? theme.colorScheme.primary
          : theme.colorScheme.outlineVariant;
    } else {
      fill = widget.active ? 0.75 : 0.05;
      color = widget.active
          ? theme.colorScheme.primary
          : theme.colorScheme.outlineVariant;
    }

    final begin = _previousFill;
    _previousFill = fill;

    return Container(
      height: 8,
      decoration: BoxDecoration(
        color: theme.colorScheme.surfaceContainerHighest,
        borderRadius: BorderRadius.circular(4),
      ),
      child: TweenAnimationBuilder<double>(
        tween: Tween<double>(begin: begin, end: fill),
        duration: const Duration(milliseconds: 120),
        curve: Curves.easeOut,
        builder: (context, animatedFill, child) {
          return FractionallySizedBox(
            alignment: AlignmentDirectional.centerStart,
            widthFactor: max(animatedFill, 0.02),
            child: child,
          );
        },
        child: Container(
          decoration: BoxDecoration(
            color: color,
            borderRadius: BorderRadius.circular(4),
          ),
        ),
      ),
    );
  }
}
