import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:syncrow_web/pages/routines/widgets/condition_toggle.dart';
import 'package:syncrow_web/pages/routines/widgets/slider_value_selector.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';

class CustomRoutinesTextbox extends StatefulWidget {
  final String? currentCondition;
  final String dialogType;
  final (double, double) sliderRange;
  final dynamic displayedValue;
  final dynamic initialValue;
  final void Function(String condition) onConditionChanged;
  final void Function(double value) onTextChanged;
  final String unit;
  final double dividendOfRange;
  final double stepIncreaseAmount;
  final bool withSpecialChar;

  const CustomRoutinesTextbox({
    required this.dialogType,
    required this.sliderRange,
    required this.displayedValue,
    required this.initialValue,
    required this.onConditionChanged,
    required this.onTextChanged,
    required this.currentCondition,
    required this.unit,
    required this.dividendOfRange,
    required this.stepIncreaseAmount,
    required this.withSpecialChar,
    super.key,
  });

  @override
  State<CustomRoutinesTextbox> createState() => _CustomRoutinesTextboxState();
}

class _CustomRoutinesTextboxState extends State<CustomRoutinesTextbox> {
  late final TextEditingController _controller;

  bool hasError = false;
  String? errorMessage;

  int getDecimalPlaces(double step) {
    String stepStr = step.toString();
    if (stepStr.contains('.')) {
      List<String> parts = stepStr.split('.');
      String decimalPart = parts[1];
      decimalPart = decimalPart.replaceAll(RegExp(r'0+$'), '');
      return decimalPart.isEmpty ? 0 : decimalPart.length;
    } else {
      return 0;
    }
  }

  bool _isInitialized = false;

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

  void _initializeController() {
    final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount);
    final dynamic initialValue = widget.initialValue;
    double parsedValue;

    if (initialValue is num) {
      parsedValue = initialValue.toDouble();
    } else if (initialValue is String) {
      parsedValue = double.tryParse(initialValue) ?? widget.sliderRange.$1;
    } else {
      parsedValue = widget.sliderRange.$1;
    }

    _controller = TextEditingController(
      text: parsedValue.toStringAsFixed(decimalPlaces),
    );
    _isInitialized = true;
  }

  @override
  void didUpdateWidget(CustomRoutinesTextbox oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.initialValue != oldWidget.initialValue && _isInitialized) {
      final decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount);
      final dynamic initialValue = widget.initialValue;
      double newValue;

      if (initialValue is num) {
        newValue = initialValue.toDouble();
      } else if (initialValue is String) {
        newValue = double.tryParse(initialValue) ?? widget.sliderRange.$1;
      } else {
        newValue = widget.sliderRange.$1;
      }

      final newValueText = newValue.toStringAsFixed(decimalPlaces);
      if (_controller.text != newValueText) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          _controller.text = newValueText;
          _controller.selection =
              TextSelection.collapsed(offset: _controller.text.length);
        });
      }
    }
  }

 

  void _validateInput(String value) {
    final doubleValue = double.tryParse(value);
    if (doubleValue == null) {
      setState(() {
        errorMessage = "Invalid number";
        hasError = true;
      });
      return;
    }

    final min = widget.sliderRange.$1;
    final max = widget.sliderRange.$2;

    if (doubleValue < min) {
      setState(() {
        errorMessage = "Value must be at least $min";
        hasError = true;
      });
    } else if (doubleValue > max) {
      setState(() {
        errorMessage = "Value must be at most $max";
        hasError = true;
      });
    } else {
      int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount);
      int factor = pow(10, decimalPlaces).toInt();
      int scaledStep = (widget.stepIncreaseAmount * factor).round();
      int scaledValue = (doubleValue * factor).round();

      if (scaledValue % scaledStep != 0) {
        setState(() {
          errorMessage = "must be a multiple of ${widget.stepIncreaseAmount}";
          hasError = true;
        });
      } else {
        setState(() {
          errorMessage = null;
          hasError = false;
        });
      }
    }
  }


  void _correctAndUpdateValue(String value) {
    final doubleValue = double.tryParse(value) ?? 0.0;
    int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount);
    double rounded = (doubleValue / widget.stepIncreaseAmount).round() *
        widget.stepIncreaseAmount;
    rounded = rounded.clamp(widget.sliderRange.$1, widget.sliderRange.$2);
    rounded = double.parse(rounded.toStringAsFixed(decimalPlaces));

    setState(() {
      hasError = false;
      errorMessage = null;
    });

    _controller.text = rounded.toStringAsFixed(decimalPlaces);
    _controller.selection = TextSelection.fromPosition(
      TextPosition(offset: _controller.text.length),
    );
    widget.onTextChanged(rounded);
  }

  @override
  Widget build(BuildContext context) {
    int decimalPlaces = getDecimalPlaces(widget.stepIncreaseAmount);

    List<TextInputFormatter> formatters = [];
    if (decimalPlaces == 0) {
      formatters.add(FilteringTextInputFormatter.digitsOnly);
    } else {
      formatters.add(FilteringTextInputFormatter.allow(
        RegExp(r'^\d*\.?\d{0,' + decimalPlaces.toString() + r'}$'),
      ));
    }
    formatters.add(RangeInputFormatter(
      min: widget.sliderRange.$1,
      max: widget.sliderRange.$2,
    ));

    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        if (widget.dialogType == 'IF')
          ConditionToggle(
            currentCondition: widget.currentCondition,
            onChanged: widget.onConditionChanged,
          ),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 35, vertical: 2),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Text(
                'Step: ${widget.stepIncreaseAmount}',
                style: context.textTheme.bodySmall?.copyWith(
                  color: ColorsManager.grayColor,
                  fontSize: 10,
                  fontWeight: FontWeight.w400,
                ),
              ),
            ],
          ),
        ),
        Center(
          child: Container(
            width: 170,
            padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
            decoration: BoxDecoration(
              color: const Color(0xFFF8F8F8),
              borderRadius: BorderRadius.circular(20),
              border: hasError
                  ? Border.all(color: Colors.red, width: 1)
                  : Border.all(
                      color: ColorsManager.lightGrayBorderColor, width: 1),
              boxShadow: [
                BoxShadow(
                  color: ColorsManager.blackColor.withOpacity(0.05),
                  blurRadius: 8,
                  offset: const Offset(0, 4),
                ),
              ],
            ),
            child: Row(
              children: [
                Expanded(
                  child: TextFormField(
                    controller: _controller,
                    style: context.textTheme.bodyLarge?.copyWith(
                      fontSize: 20,
                      fontWeight: FontWeight.bold,
                      color: ColorsManager.blackColor,
                    ),
                    keyboardType: TextInputType.number,
                    inputFormatters: [
                      FilteringTextInputFormatter.allow(
                        widget.withSpecialChar
                            ? RegExp(r'^-?\d*\.?\d{0,' +
                                decimalPlaces.toString() +
                                r'}$')
                            : RegExp(r'\d+'),
                      ),
                    ],
                    decoration: const InputDecoration(
                      border: InputBorder.none,
                      isDense: true,
                      contentPadding: EdgeInsets.zero,
                    ),
                    onChanged: _validateInput,
                    onFieldSubmitted: _correctAndUpdateValue,
                    onTapOutside: (_) =>
                        _correctAndUpdateValue(_controller.text),
                  ),
                ),
                const SizedBox(width: 12),
                Text(
                  widget.unit,
                  style: context.textTheme.bodyMedium?.copyWith(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: ColorsManager.vividBlue,
                  ),
                ),
              ],
            ),
          ),
        ),
        if (errorMessage != null)
          Padding(
            padding: const EdgeInsets.only(top: 2.0),
            child: Text(
              errorMessage!,
              style: context.textTheme.bodySmall?.copyWith(
                color: Colors.red,
                fontSize: 10,
              ),
            ),
          ),
        const SizedBox(height: 16),
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 32),
          child: Wrap(
            alignment: WrapAlignment.spaceBetween,
            direction: Axis.horizontal,
            children: [
              Text(
                'Min. ${widget.sliderRange.$1.toInt()}${widget.unit}',
                style: context.textTheme.bodySmall?.copyWith(
                  color: ColorsManager.grayColor,
                  fontSize: 10,
                  fontWeight: FontWeight.w400,
                ),
              ),
              const SizedBox(
                width: 50,
              ),
              Text(
                'Max. ${widget.sliderRange.$2.toInt()}${widget.unit}',
                style: context.textTheme.bodySmall?.copyWith(
                  color: ColorsManager.grayColor,
                  fontSize: 10,
                  fontWeight: FontWeight.w400,
                ),
              ),
            ],
          ),
        ),
        const SizedBox(height: 16),
      ],
    );
  }
}
