import 'dart:async';
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 (≥500 ms) → records audio to a temp file.
/// • Release → stops recording and calls [onAudioReady] with the file path.
/// • Slide up while holding → cancels recording without sending.
///
/// Uses [Listener] (raw pointer events) instead of [GestureDetector] so that
/// the inner [IconButton] tooltip/InkWell never steals the gesture.
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;
  bool _pointerDown = false;
  Timer? _longPressTimer;

  // 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() {
    _longPressTimer?.cancel();
    _recorder.dispose();
    _pulseController.dispose();
    super.dispose();
  }

  Future<void> _startRecording() async {
    if (!mounted) return;
    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,
    );

    if (mounted) {
      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();
    if (mounted) setState(() => _isRecording = false);

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

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

    widget.onAudioReady(path);
  }

  void _onPointerDown(PointerDownEvent event) {
    if (widget.disabled) return;
    _pressOrigin = event.position;
    _pointerDown = true;
    _cancelled = false;
    _longPressTimer?.cancel();
    // Start recording after 500 ms hold
    _longPressTimer = Timer(const Duration(milliseconds: 500), () {
      if (_pointerDown && mounted) _startRecording();
    });
  }

  void _onPointerMove(PointerMoveEvent event) {
    if (_pressOrigin == null || !_isRecording) return;
    final dy = _pressOrigin!.dy - event.position.dy;
    setState(() => _cancelled = dy > _cancelThreshold);
  }

  void _onPointerUp(PointerUpEvent event) {
    _pointerDown = false;
    _longPressTimer?.cancel();
    _stopRecording(cancel: _cancelled);
    _pressOrigin = null;
  }

  void _onPointerCancel(PointerCancelEvent event) {
    _pointerDown = false;
    _longPressTimer?.cancel();
    _stopRecording(cancel: true);
    _pressOrigin = null;
  }

  @override
  Widget build(BuildContext context) {
    return Listener(
      onPointerDown: _onPointerDown,
      onPointerMove: _onPointerMove,
      onPointerUp: _onPointerUp,
      onPointerCancel: _onPointerCancel,
      child: _isRecording ? _buildRecordingWidget() : _buildIdleWidget(),
    );
  }

  Widget _buildIdleWidget() {
    return IconButton(
      icon: Icon(
        Icons.mic_none,
        size: 22,
        color: widget.disabled ? AppColors.textMuted : null,
      ),
      tooltip: '按住录音',
      onPressed: widget.disabled ? null : () {},
    );
  }

  Widget _buildRecordingWidget() {
    return 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: _cancelled ? AppColors.textMuted : AppColors.error,
            ),
          ),
          const SizedBox(width: 4),
          Text(
            _cancelled ? '松开取消' : '松开发送',
            style: TextStyle(
              fontSize: 12,
              color: _cancelled ? AppColors.textMuted : AppColors.error,
            ),
          ),
        ],
      ),
    );
  }
}
