import 'package:ecosim/src/common/widgets/color_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class ColorSlider extends ConsumerStatefulWidget {
  const ColorSlider({
    super.key,
  });

  @override
  ConsumerState<ColorSlider> createState() => _ColorSliderState();
}

class _ColorSliderState extends ConsumerState<ColorSlider> {
  final List<Color> _colors = [
    const Color.fromARGB(255, 255, 0, 0),
    const Color.fromARGB(255, 255, 128, 0),
    const Color.fromARGB(255, 255, 255, 0),
    const Color.fromARGB(255, 128, 255, 0),
    const Color.fromARGB(255, 0, 255, 0),
    const Color.fromARGB(255, 0, 255, 128),
    const Color.fromARGB(255, 0, 255, 255),
    const Color.fromARGB(255, 0, 128, 255),
    const Color.fromARGB(255, 0, 0, 255),
    const Color.fromARGB(255, 127, 0, 255),
    const Color.fromARGB(255, 255, 0, 255),
    const Color.fromARGB(255, 255, 0, 127),
    const Color.fromARGB(255, 128, 128, 128),
    const Color.fromARGB(255, 255, 255, 255),
  ];

  double _colorSliderPosition = 0;
  Color _currentColor = Colors.white;

  void _colorChangeHandler(double position, BoxConstraints constraints) {
    // handle out of bounds positions
    final width = constraints.maxWidth - 8;
    if (position > width) {
      position = width;
    }
    if (position < 8) {
      position = 8;
    }
    setState(() {
      _colorSliderPosition = position;
    });
    ref.read(colorSliderSelectionProvider.notifier).state =
        _calculateSelectedColor(position, constraints);
  }

  // double _calculateStartPosition(Color startColor, BoxConstraints constraints) {
  //   final width = constraints.maxWidth;
  //   // determine
  //   // double positionInColorArray =
  //   return 0;
  // }

  Color _calculateSelectedColor(double position, BoxConstraints constraints) {
    final width = constraints.maxWidth;
    // determine color
    double positionInColorArray = (position / width * (_colors.length - 1));
    // print(positionInColorArray);
    int index = positionInColorArray.truncate();
    // print(index);
    double remainder = positionInColorArray - index;

    if (remainder == 0.0) {
      _currentColor = _colors[index];
    } else {
      // calculate new color
      int redValue = _colors[index].red == _colors[index + 1].red
          ? _colors[index].red
          : (_colors[index].red +
                  (_colors[index + 1].red - _colors[index].red) * remainder)
              .round();
      int greenValue = _colors[index].green == _colors[index + 1].green
          ? _colors[index].green
          : (_colors[index].green +
                  (_colors[index + 1].green - _colors[index].green) * remainder)
              .round();
      int blueValue = _colors[index].blue == _colors[index + 1].blue
          ? _colors[index].blue
          : (_colors[index].blue +
                  (_colors[index + 1].blue - _colors[index].blue) * remainder)
              .round();
      _currentColor = Color.fromARGB(255, redValue, greenValue, blueValue);
    }
    return _currentColor;
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        _currentColor =
            _calculateSelectedColor(_colorSliderPosition, constraints);

        return GestureDetector(
          behavior: HitTestBehavior.opaque,
          onHorizontalDragStart: (details) =>
              _colorChangeHandler(details.localPosition.dx, constraints),
          onHorizontalDragUpdate: (details) =>
              _colorChangeHandler(details.localPosition.dx, constraints),
          onTapDown: (details) =>
              _colorChangeHandler(details.localPosition.dx, constraints),
          child: Container(
            width: double.infinity,
            height: 24,
            decoration: BoxDecoration(
              border: Border.all(
                width: 2,
                color: Colors.white,
              ),
              borderRadius: BorderRadius.circular(6),
              gradient: LinearGradient(colors: _colors),
            ),
            child: CustomPaint(
              painter: SliderIndicatorPainter(
                position: _colorSliderPosition,
                color: _currentColor,
              ),
            ),
          ),
        );
      },
    );
  }
}

class SliderIndicatorPainter extends CustomPainter {
  final double position;
  final Color color;

  SliderIndicatorPainter({
    required this.position,
    required this.color,
  });

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawCircle(
      Offset(position, size.height / 2),
      16,
      Paint()..color = color,
    );
    canvas.drawCircle(
      Offset(position, size.height / 2),
      16,
      Paint()
        ..color = Colors.white
        ..style = PaintingStyle.stroke
        ..strokeWidth = 2,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
