import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';
import '../../../../core/theme/app_colors.dart';

/// WhatsApp-style press-and-hold mic button.
///
/// • Press and hold → records audio to a temp file.
/// • Release → stops recording and calls [onAudioReady] with the file path.
/// • Slide up while holding → cancels recording without sending.
///
/// Requires microphone permission (handled by the `record` package).
class VoiceMicButton extends StatefulWidget {
  /// Called with the temp file path when the user releases the button.
  final void Function(String audioPath) onAudioReady;

  /// Whether the button should be disabled (e.g. awaiting approval).
  final bool disabled;

  const VoiceMicButton({
    super.key,
    required this.onAudioReady,
    this.disabled = false,
  });

  @override
  State<VoiceMicButton> createState() => _VoiceMicButtonState();
}

class _VoiceMicButtonState extends State<VoiceMicButton>
    with SingleTickerProviderStateMixin {
  final _recorder = AudioRecorder();
  bool _isRecording = false;
  bool _cancelled = false;

  // Slide-up cancel threshold (pixels above press origin)
  static const double _cancelThreshold = 60.0;
  Offset? _pressOrigin;

  late final AnimationController _pulseController;
  late final Animation<double> _pulseAnimation;

  @override
  void initState() {
    super.initState();
    _pulseController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 800),
    );
    _pulseAnimation = Tween<double>(begin: 1.0, end: 1.25).animate(
      CurvedAnimation(parent: _pulseController, curve: Curves.easeInOut),
    );
  }

  @override
  void dispose() {
    _recorder.dispose();
    _pulseController.dispose();
    super.dispose();
  }

  Future<void> _startRecording() async {
    final hasPermission = await _recorder.hasPermission();
    if (!hasPermission) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('需要麦克风权限')),
        );
      }
      return;
    }

    final dir = await getTemporaryDirectory();
    final path = '${dir.path}/voice_${DateTime.now().millisecondsSinceEpoch}.m4a';

    await _recorder.start(
      const RecordConfig(encoder: AudioEncoder.aacLc, sampleRate: 16000),
      path: path,
    );

    setState(() {
      _isRecording = true;
      _cancelled = false;
    });
    _pulseController.repeat(reverse: true);
  }

  Future<void> _stopRecording({required bool cancel}) async {
    if (!_isRecording) return;

    _pulseController.stop();
    _pulseController.reset();

    final path = await _recorder.stop();
    setState(() => _isRecording = false);

    if (cancel || path == null) return;

    // Ignore empty recordings (< ~0.3s)
    try {
      final size = await File(path).length();
      if (size < 2048) return;
    } catch (_) {
      return;
    }

    widget.onAudioReady(path);
  }

  void _onLongPressStart(LongPressStartDetails details) {
    if (widget.disabled) return;
    _pressOrigin = details.globalPosition;
    _startRecording();
  }

  void _onLongPressMoveUpdate(LongPressMoveUpdateDetails details) {
    if (_pressOrigin == null || !_isRecording) return;
    final dy = _pressOrigin!.dy - details.globalPosition.dy;
    setState(() => _cancelled = dy > _cancelThreshold);
  }

  void _onLongPressEnd(LongPressEndDetails details) {
    _stopRecording(cancel: _cancelled);
    _pressOrigin = null;
  }

  void _onLongPressCancel() {
    _stopRecording(cancel: true);
    _pressOrigin = null;
  }

  @override
  Widget build(BuildContext context) {
    if (_isRecording) {
      return _buildRecordingButton();
    }
    return GestureDetector(
      onLongPressStart: _onLongPressStart,
      onLongPressMoveUpdate: _onLongPressMoveUpdate,
      onLongPressEnd: _onLongPressEnd,
      onLongPressCancel: _onLongPressCancel,
      child: IconButton(
        icon: Icon(
          Icons.mic_none,
          size: 22,
          color: widget.disabled ? AppColors.textMuted : null,
        ),
        tooltip: '按住录音',
        onPressed: widget.disabled ? null : () {},
      ),
    );
  }

  Widget _buildRecordingButton() {
    final isCancelling = _cancelled;
    return GestureDetector(
      onLongPressMoveUpdate: _onLongPressMoveUpdate,
      onLongPressEnd: _onLongPressEnd,
      onLongPressCancel: _onLongPressCancel,
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            ScaleTransition(
              scale: _pulseAnimation,
              child: Icon(
                Icons.mic,
                size: 22,
                color: isCancelling ? AppColors.textMuted : AppColors.error,
              ),
            ),
            const SizedBox(width: 4),
            Text(
              isCancelling ? '松开取消' : '松开发送',
              style: TextStyle(
                fontSize: 12,
                color: isCancelling ? AppColors.textMuted : AppColors.error,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
