import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hmg_patient_app_new/core/app_export.dart';
import 'package:hmg_patient_app_new/presentation/symptoms_checker/user_info_selection/widgets/triangle_indicator.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';

class HeightScale extends StatefulWidget {
  final double minValue;
  final double maxValue;
  final double initialHeight;
  final bool isCm;
  final ValueChanged<double>? onHeightChanged;

  // Feedback config
  final bool enableHaptic;
  final bool enableSound;
  final Duration feedbackDebounce;

  const HeightScale({
    super.key,
    required this.minValue,
    required this.maxValue,
    required this.initialHeight,
    required this.isCm,
    this.onHeightChanged,
    this.enableHaptic = true,
    this.enableSound = true,
    this.feedbackDebounce = const Duration(milliseconds: 80),
  });

  @override
  State<HeightScale> createState() => _HeightScaleState();
}

class _HeightScaleState extends State<HeightScale> {
  late FixedExtentScrollController _scrollController;

  // Debounce timer used for playing feedback only after small pause
  Timer? _feedbackTimer;

  // Get increment based on unit (CM = 1.0, FT = 0.1)
  double get _increment => widget.isCm ? 1.0 : 0.1;

  late final int _childCount;

  @override
  void initState() {
    super.initState();
    // prepare child count and initial index using normal order (min at index 0)
    _childCount = ((widget.maxValue - widget.minValue) / _increment).round() + 1;
    // initialIndex should point to position of initialHeight in normal list
    int initialIndex = ((widget.initialHeight - widget.minValue) / _increment).round();
    if (initialIndex < 0) initialIndex = 0;
    if (initialIndex >= _childCount) initialIndex = _childCount - 1;
    _scrollController = FixedExtentScrollController(initialItem: initialIndex);
  }

  // Schedule haptic + sound feedback with debounce (prevents spamming during fling)
  void _scheduleFeedback() {
    if (!(widget.enableHaptic || widget.enableSound)) return;

    _feedbackTimer?.cancel();
    _feedbackTimer = Timer(widget.feedbackDebounce, () {
      // Haptic
      if (widget.enableHaptic) {
        // selection click is lightweight and appropriate for wheel ticks
        HapticFeedback.selectionClick();
      }
      // Sound
      if (widget.enableSound) {
        // simple system click - note: may be muted by device settings
        SystemSound.play(SystemSoundType.click);
      }
    });
  }

  @override
  void dispose() {
    _feedbackTimer?.cancel();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final pointerSize = 20.w;
    final pickerHeight = 300.h;
    final pointerTop = (pickerHeight / 2) - (pointerSize / 2);

    return SizedBox(
      height: pickerHeight,
      child: Stack(
        children: [
          // Scrollable wheel picker
          ListWheelScrollView.useDelegate(
            controller: _scrollController,
            itemExtent: 10.h,
            diameterRatio: 2.0,
            squeeze: 1.2,
            perspective: 0.001,
            physics: const BouncingScrollPhysics(),
            onSelectedItemChanged: (index) {
              // Map index (0..n-1) to value normal: value = min + index*increment
              final selectedValue = widget.minValue + (index * _increment);
              widget.onHeightChanged?.call(selectedValue);
              _scheduleFeedback();
            },
            childDelegate: ListWheelChildBuilderDelegate(
              childCount: _childCount,
              builder: (context, index) {
                // Displayed height value for this index (normal order)
                final height = widget.minValue + (index * _increment);

                // For CM: main mark every 10, mid mark every 5
                // For FT: main mark every 1.0 (10 ticks), mid mark every 0.5 (5 ticks)
                final isMainMark = widget.isCm ? height.round() % 10 == 0 : ((height * 10).round() % 10 == 0);
                final isMidMark = widget.isCm ? height.round() % 5 == 0 : ((height * 10).round() % 5 == 0);

                return SizedBox(
                  width: 100.w,
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      // Number label for main marks
                      if (isMainMark)
                        SizedBox(
                          width: 30.w,
                          child: Text(
                            widget.isCm ? height.round().toString() : height.toStringAsFixed(1),
                            style: TextStyle(
                                fontSize: 11.f,
                                color: AppColors.greyTextColor,
                                fontWeight: FontWeight.w600,
                                height: isFoldable ? 0.5 : 1,
                                fontFamily: "Poppins"),
                            textAlign: TextAlign.right,
                          ),
                        )
                      else
                        SizedBox(width: 30.w),
                      SizedBox(width: 4.w),
                      // Ruler mark
                      Container(
                        width: isMainMark
                            ? 40.w
                            : isMidMark
                                ? 30.w
                                : 25.w,
                        height: isMainMark || isMidMark ? 2.5.h : 1.5.h,
                        decoration: BoxDecoration(
                          color: isMainMark
                              ? AppColors.textColor
                              : isMidMark
                                  ? AppColors.textColorLight
                                  : AppColors.textColorLight.withValues(alpha: 0.5),
                          borderRadius: BorderRadius.circular(2.r),
                        ),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
          // Triangle indicator pointing to selected value
          Positioned(
            right: 0,
            top: pointerTop,
            child: TriangleIndicator(pointerSize: pointerSize),
          ),
        ],
      ),
    );
  }
}
