import 'dart:async';

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

enum RecordingTouchLockUnlockIntent { unlockOnly, stopRecording }

RecordingTouchLockUnlockIntent resolveRecordingTouchLockUnlockIntent({
  required Offset position,
  required Size size,
  double stopZoneFraction = 0.3,
}) {
  if (size.width <= 0 || size.height <= 0 || stopZoneFraction <= 0) {
    return RecordingTouchLockUnlockIntent.unlockOnly;
  }

  final normalizedStopZone = stopZoneFraction.clamp(0.0, 1.0);
  if (size.width <= size.height) {
    final stopZoneTop = size.height * (1 - normalizedStopZone);
    return position.dy >= stopZoneTop
        ? RecordingTouchLockUnlockIntent.stopRecording
        : RecordingTouchLockUnlockIntent.unlockOnly;
  }

  final stopZoneLeft = size.width * (1 - normalizedStopZone);
  return position.dx >= stopZoneLeft
      ? RecordingTouchLockUnlockIntent.stopRecording
      : RecordingTouchLockUnlockIntent.unlockOnly;
}

class RecordingTouchLockOverlayWidget extends StatefulWidget {
  const RecordingTouchLockOverlayWidget({
    super.key,
    required this.enabled,
    required this.onUnlocked,
    this.unlockHoldDuration = const Duration(seconds: 2),
  });

  final bool enabled;
  final ValueChanged<RecordingTouchLockUnlockIntent> onUnlocked;
  final Duration unlockHoldDuration;

  @override
  State<RecordingTouchLockOverlayWidget> createState() =>
      _RecordingTouchLockOverlayWidgetState();
}

class _RecordingTouchLockOverlayWidgetState
    extends State<RecordingTouchLockOverlayWidget> {
  Timer? _holdTimer;
  bool _isHolding = false;
  int? _remainingSeconds;
  Offset? _holdStartPosition;
  Size? _holdStartSize;

  @override
  void didUpdateWidget(RecordingTouchLockOverlayWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (!widget.enabled) {
      _cancelHold();
    }
  }

  @override
  void dispose() {
    _holdTimer?.cancel();
    _holdTimer = null;
    super.dispose();
  }

  void _cancelHold() {
    _holdTimer?.cancel();
    _holdTimer = null;
    if (!_isHolding && _remainingSeconds == null) return;
    setState(() {
      _isHolding = false;
      _remainingSeconds = null;
      _holdStartPosition = null;
      _holdStartSize = null;
    });
  }

  void _startHold(Offset position, Size size) {
    if (!widget.enabled) return;
    final totalSeconds = widget.unlockHoldDuration.inSeconds;
    _holdTimer?.cancel();
    setState(() {
      _isHolding = true;
      _remainingSeconds = totalSeconds;
      _holdStartPosition = position;
      _holdStartSize = size;
    });

    var elapsed = 0;
    _holdTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      elapsed += 1;
      if (!mounted) {
        timer.cancel();
        return;
      }
      if (elapsed >= totalSeconds) {
        timer.cancel();
        _holdTimer = null;
        final intent = resolveRecordingTouchLockUnlockIntent(
          position: _holdStartPosition ?? Offset.zero,
          size: _holdStartSize ?? Size.zero,
        );
        setState(() {
          _isHolding = false;
          _remainingSeconds = null;
          _holdStartPosition = null;
          _holdStartSize = null;
        });
        widget.onUnlocked(intent);
        return;
      }
      setState(() => _remainingSeconds = totalSeconds - elapsed);
    });
  }

  @override
  Widget build(BuildContext context) {
    if (!widget.enabled) {
      return const SizedBox.shrink();
    }

    return Positioned.fill(
      child: LayoutBuilder(
        builder: (context, constraints) {
          final overlaySize = Size(constraints.maxWidth, constraints.maxHeight);
          return Listener(
            behavior: HitTestBehavior.opaque,
            onPointerDown: (event) =>
                _startHold(event.localPosition, overlaySize),
            onPointerUp: (_) => _cancelHold(),
            onPointerCancel: (_) => _cancelHold(),
            child: ColoredBox(
              color: Colors.black.withValues(alpha: 0.01),
              child: Align(
                alignment: Alignment.topCenter,
                child: Padding(
                  padding: EdgeInsets.only(top: 68.r),
                  child: DecoratedBox(
                    decoration: BoxDecoration(
                      color: Colors.black54,
                      borderRadius: BorderRadius.circular(24.r),
                    ),
                    child: Padding(
                      padding: EdgeInsets.symmetric(
                        horizontal: 16.r,
                        vertical: 8.r,
                      ),
                      child: _isHolding && _remainingSeconds != null
                          ? Builder(
                              builder: (context) {
                                final remainingSeconds = _remainingSeconds!;
                                return Column(
                                  mainAxisSize: MainAxisSize.min,
                                  children: [
                                    AnimatedSwitcher(
                                      duration: const Duration(
                                        milliseconds: 280,
                                      ),
                                      switchInCurve: Curves.easeOut,
                                      switchOutCurve: Curves.easeIn,
                                      transitionBuilder: (child, animation) {
                                        return ScaleTransition(
                                          scale: Tween<double>(
                                            begin: 0.6,
                                            end: 1,
                                          ).animate(animation),
                                          child: FadeTransition(
                                            opacity: animation,
                                            child: child,
                                          ),
                                        );
                                      },
                                      child: Text(
                                        '${remainingSeconds}s',
                                        key: ValueKey<int>(remainingSeconds),
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 18.sp,
                                          fontWeight: FontWeight.w600,
                                          height: 1.1,
                                        ),
                                      ),
                                    ),
                                    SizedBox(height: 2.r),
                                    Text(
                                      '保持按住解锁',
                                      style: TextStyle(
                                        color: Colors.white70,
                                        fontSize: 10.sp,
                                      ),
                                    ),
                                  ],
                                );
                              },
                            )
                          : Text(
                              '防误触已开启，按住 ${widget.unlockHoldDuration.inSeconds}s 解锁',
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: 10.sp,
                              ),
                            ),
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}
