import 'package:flutter/material.dart';
import 'package:plezy/widgets/app_icon.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../theme/mono_tokens.dart';
import '../utils/platform_detector.dart';

/// A wrapper widget that adds hover-activated navigation arrows to horizontal scrolling content.
/// The arrows only appear on desktop/web platforms and hide at scroll boundaries.
///
/// This widget creates and manages its own ScrollController internally. Use the [builder]
/// constructor to access the ScrollController for the scrollable child widget.
class HorizontalScrollWithArrows extends StatefulWidget {
  final Widget Function(ScrollController) builder;
  final double scrollAmount;
  final ScrollController? controller;

  const HorizontalScrollWithArrows({
    super.key,
    required this.builder,
    this.scrollAmount = 0.8, // Scroll by 80% of viewport width by default
    this.controller,
  });

  @override
  State<HorizontalScrollWithArrows> createState() => _HorizontalScrollWithArrowsState();
}

class _HorizontalScrollWithArrowsState extends State<HorizontalScrollWithArrows> {
  late final ScrollController _scrollController;
  late final bool _ownsController;
  bool _isHovering = false;
  bool _canScrollLeft = false;
  bool _canScrollRight = false;

  @override
  void initState() {
    super.initState();
    _ownsController = widget.controller == null;
    _scrollController = widget.controller ?? ScrollController();
    _scrollController.addListener(_updateScrollState);
    WidgetsBinding.instance.addPostFrameCallback((_) => _updateScrollState());
  }

  @override
  void dispose() {
    _scrollController.removeListener(_updateScrollState);
    if (_ownsController) {
      _scrollController.dispose();
    }
    super.dispose();
  }

  void _updateScrollState() {
    if (!mounted || _scrollController.positions.length != 1) {
      if (mounted && (_canScrollLeft || _canScrollRight)) {
        setState(() {
          _canScrollLeft = false;
          _canScrollRight = false;
        });
      }
      return;
    }

    final position = _scrollController.position;
    final isScrollable = position.maxScrollExtent > 0;
    final newLeft = isScrollable && position.pixels > 0;
    final newRight = isScrollable && position.pixels < position.maxScrollExtent;
    if (newLeft != _canScrollLeft || newRight != _canScrollRight) {
      setState(() {
        _canScrollLeft = newLeft;
        _canScrollRight = newRight;
      });
    }
  }

  void _animateScroll(double direction) {
    if (_scrollController.positions.length != 1) return;
    final position = _scrollController.position;
    final delta = direction * position.viewportDimension * widget.scrollAmount;
    final targetScroll = (position.pixels + delta).clamp(0.0, position.maxScrollExtent);
    _scrollController.animateTo(targetScroll, duration: tokens(context).slow, curve: Curves.easeInOut);
  }

  void _scrollLeft() => _animateScroll(-1);

  void _scrollRight() => _animateScroll(1);

  Widget _buildArrowButton({
    required double position,
    required IconData icon,
    required VoidCallback onPressed,
    required bool canScroll,
  }) {
    return Positioned(
      left: position < 0 ? null : position,
      right: position < 0 ? -position : null,
      top: 0,
      bottom: 0,
      child: Center(
        child: AnimatedOpacity(
          opacity: (_isHovering && canScroll) ? 1.0 : 0.0,
          duration: const Duration(milliseconds: 200),
          curve: Curves.easeInOut,
          child: IgnorePointer(
            ignoring: !(_isHovering && canScroll),
            child: _NavigationArrow(icon: icon, onPressed: onPressed),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final child = widget.builder(_scrollController);

    if (!PlatformDetector.isDesktop(context)) {
      return child;
    }

    return MouseRegion(
      onEnter: (_) => setState(() => _isHovering = true),
      onExit: (_) => setState(() => _isHovering = false),
      child: NotificationListener<ScrollMetricsNotification>(
        onNotification: (_) {
          _updateScrollState();
          return false;
        },
        child: Stack(
          children: [
            child,
            _buildArrowButton(
              position: 8,
              icon: Symbols.chevron_left_rounded,
              onPressed: _scrollLeft,
              canScroll: _canScrollLeft,
            ),
            _buildArrowButton(
              position: -8,
              icon: Symbols.chevron_right_rounded,
              onPressed: _scrollRight,
              canScroll: _canScrollRight,
            ),
          ],
        ),
      ),
    );
  }
}

class _NavigationArrow extends StatefulWidget {
  final IconData icon;
  final VoidCallback onPressed;

  const _NavigationArrow({required this.icon, required this.onPressed});

  @override
  State<_NavigationArrow> createState() => _NavigationArrowState();
}

class _NavigationArrowState extends State<_NavigationArrow> {
  bool _isPressed = false;

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      cursor: SystemMouseCursors.click,
      child: GestureDetector(
        onTapDown: (_) => setState(() => _isPressed = true),
        onTapUp: (_) {
          setState(() => _isPressed = false);
          widget.onPressed();
        },
        onTapCancel: () => setState(() => _isPressed = false),
        child: Container(
          width: 48,
          height: 48,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: Colors.black.withValues(alpha: _isPressed ? 0.9 : 0.7),
            boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.3), blurRadius: 8, spreadRadius: 0)],
          ),
          child: AppIcon(widget.icon, fill: 1, color: Colors.white, size: 32),
        ),
      ),
    );
  }
}
