import 'dart:ui' show lerpDouble;

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

/// 录制控制按钮：白圈 + 红色内芯，录制中为圆角矩形。
class RecordingControlButton extends StatefulWidget {
  const RecordingControlButton({
    super.key,
    required this.isRecording,
    required this.onTap,
    this.isStartingRecording = false,
    this.enabled = true,
    this.size,
  });

  final bool isRecording;
  final bool isStartingRecording;
  final VoidCallback? onTap;
  final bool enabled;
  final double? size;

  @override
  State<RecordingControlButton> createState() => _RecordingControlButtonState();
}

class _RecordingControlButtonState extends State<RecordingControlButton>
    with TickerProviderStateMixin {
  static const _morphDuration = Duration(milliseconds: 380);
  static const _pressDownDuration = Duration(milliseconds: 120);
  static const _pressUpDuration = Duration(milliseconds: 180);

  late final AnimationController _morphController;
  late final AnimationController _pressController;
  late final CurvedAnimation _morphAnimation;
  late final Animation<double> _pressScale;

  bool get _targetIsRecording =>
      widget.isRecording || widget.isStartingRecording;

  @override
  void initState() {
    super.initState();
    _morphController = AnimationController(
      vsync: this,
      duration: _morphDuration,
      value: _targetIsRecording ? 1 : 0,
    );
    _morphAnimation = CurvedAnimation(
      parent: _morphController,
      curve: Curves.easeOutCubic,
      reverseCurve: Curves.easeInCubic,
    );
    _pressController = AnimationController(
      vsync: this,
      duration: _pressDownDuration,
    );
    _pressScale = Tween<double>(begin: 1, end: 0.94).animate(
      CurvedAnimation(
        parent: _pressController,
        curve: Curves.easeOut,
        reverseCurve: Curves.easeOutBack,
      ),
    );
  }

  @override
  void didUpdateWidget(covariant RecordingControlButton oldWidget) {
    super.didUpdateWidget(oldWidget);
    final oldTarget =
        oldWidget.isRecording || oldWidget.isStartingRecording;
    final newTarget = _targetIsRecording;
    if (oldTarget != newTarget) {
      if (newTarget) {
        _morphController.forward();
      } else {
        _morphController.reverse();
      }
    }
  }

  @override
  void dispose() {
    _morphAnimation.dispose();
    _morphController.dispose();
    _pressController.dispose();
    super.dispose();
  }

  void _handlePressDown() {
    if (!widget.enabled) return;
    _pressController.duration = _pressDownDuration;
    _pressController.forward();
  }

  void _handlePressUp() {
    if (!widget.enabled) return;
    _pressController.duration = _pressUpDuration;
    _pressController.reverse();
  }

  @override
  Widget build(BuildContext context) {
    final buttonSize = widget.size ?? 70.r;
    final borderWidth = 4.r;
    final idleInnerSize = 62.r;
    final recordingInnerSize = 22.r;
    final idleCornerRadius = idleInnerSize / 2;
    final recordingCornerRadius = 6.r;

    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTapDown: (_) => _handlePressDown(),
      onTapUp: (_) => _handlePressUp(),
      onTapCancel: _handlePressUp,
      onTap: widget.enabled ? widget.onTap : null,
      child: AnimatedBuilder(
        animation: Listenable.merge([_morphController, _pressController]),
        builder: (context, child) {
          final morph = _morphAnimation.value;

          final innerSize = lerpDouble(
            idleInnerSize,
            recordingInnerSize,
            morph,
          )!;
          final cornerRadius = lerpDouble(
            idleCornerRadius,
            recordingCornerRadius,
            morph,
          )!;

          return Transform.scale(
            scale: _pressScale.value,
            child: SizedBox(
              width: buttonSize,
              height: buttonSize,
              child: Stack(
                alignment: Alignment.center,
                children: [
                  Container(
                    width: buttonSize,
                    height: buttonSize,
                    decoration: BoxDecoration(
                      shape: BoxShape.circle,
                      border: Border.all(color: Colors.white, width: borderWidth),
                    ),
                  ),
                  Container(
                    width: innerSize,
                    height: innerSize,
                    decoration: BoxDecoration(
                      color: Colors.red,
                      borderRadius: BorderRadius.circular(cornerRadius),
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}
