import 'dart:ui';
import 'package:country_code_picker/country_code_picker.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:get/get.dart';

import '../../core/constants/translation_keys.dart';
import '../../res/app_colors.dart';
import '../../res/app_theme.dart';
import '../custom_dropdown.dart';
import '../custom_text.dart';
import 'custom_dropdown_bottom_sheet.dart';


class InputField extends GetView {
  final FormFieldValidator<String>? validator;
  GlobalKey<FormFieldState>? refKey;
  String labelText = "";
  String hintText = "";
  RxString errorTextMessage = "".obs;
  final RxBool _passwordVisible = true.obs;
  int? radius = 100;
  EdgeInsetsGeometry? contentPadding = const EdgeInsets.symmetric(horizontal: 15, vertical: 15);

  // String errorText = "";

  bool isRequired = true;
  bool requiredPasswordIcon = false;
  Function(String?)? onChanged;
  FocusNode? focusNode = FocusNode();
  Function(DropDown?)? onItemSelected;
  Rx<CountryCode> selectedCountryCode = CountryCode().obs;

  Rx<DropDown>? selectedOption;

  // DropDown? selectedOption;
  final bool enabled;
  bool isDropDown = false;
  bool isTopMarginRequired = true;
  bool isCountryPicker = false;
  bool isBoxDecoration = true;
  bool showLabel = true;
  String? dropDownType = DropDownType.NORMAL;
  List<DropDown>? items;
  final AutovalidateMode autovalidateMode;
  final String? restorationId;
  InputDecoration? decoration;
  TextEditingController? controller;
  TextInputType? keyboardType;
  final TextInputAction? textInputAction;
  final TextCapitalization textCapitalization;
  final TextStyle? style;
  final StrutStyle? strutStyle;
  TextAlign textAlign;
  final TextAlignVertical? textAlignVertical;
  final TextDirection? textDirection;
  final bool autofocus;
  final String obscuringCharacter;
  bool isPassword = false;
  bool autocorrect = false;
  final SmartDashesType? smartDashesType;
  final SmartQuotesType? smartQuotesType;
  final bool enableSuggestions;
  int maxLines;
  int minLines;
  bool expands;
  final int? maxLength;
  final MaxLengthEnforcement? maxLengthEnforcement;
  final VoidCallback? onEditingComplete;
  final ValueChanged<String?>? onSubmitted;
  final List<TextInputFormatter>? inputFormatters;
  bool showCursor = true;
  double cursorWidth = 5.0;
  double cursorHeight = 15.0;
  Radius cursorRadius = const Radius.circular(10.0);
  Color cursorColor = AppThemeData.inputTextColor;
  final BoxHeightStyle selectionHeightStyle;
  final BoxWidthStyle selectionWidthStyle;
  final Brightness? keyboardAppearance;
  final EdgeInsets scrollPadding;
  final bool enableInteractiveSelection;
  Widget? prefixIcon;
  Widget? suffixIcon;
  final DragStartBehavior dragStartBehavior;
  final Function()? onClick;
  final TapRegionCallback? onTapOutside;
  final MouseCursor? mouseCursor;
  final InputCounterWidgetBuilder? buildCounter;
  final ScrollPhysics? scrollPhysics;
  final ScrollController? scrollController;
  final Iterable<String>? autofillHints;
  final TextMagnifierConfiguration? magnifierConfiguration;
  bool readOnly;
  final ContentInsertionConfiguration? contentInsertionConfiguration;
  SpellCheckConfiguration? spellCheckConfiguration;
  final String? prefixText;
  final String? prefixCode;
  final double? inputFontSize;
  final FontWeight? inputFontWeight;
  final Color? inputColor;

  final Rx<Color> inputErrorColor = Rx<Color>(Colors.black);
  final Rx<Color> inputErrorBorderColor = Rx<Color>(Colors.black);
  RxBool isError = false.obs;

  InputField({
    this.refKey,
    this.controller,
    this.labelText = "",
    this.hintText = "",
    // this.errorText = "",
    this.isRequired = true,
    this.requiredPasswordIcon = false,
    this.isBoxDecoration = true,
    this.showLabel = true,
    this.isTopMarginRequired = true,
    this.isDropDown = false,
    this.isCountryPicker = false,
    this.dropDownType,
    this.inputFontSize,
    this.inputFontWeight,
    this.inputColor,
    this.validator,
    this.contentPadding = const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
    this.items,
    this.radius = 100,
    this.decoration,
    this.focusNode,
    this.onChanged,
    this.onItemSelected,
    this.prefixIcon,
    this.suffixIcon,
    this.selectedOption,
    this.enabled = true,
    this.autovalidateMode = AutovalidateMode.disabled,
    this.restorationId,
    this.readOnly = false,
    this.isPassword = false,
    this.textCapitalization = TextCapitalization.none,
    this.scrollPadding = const EdgeInsets.all(20.0),
    this.enableInteractiveSelection = true,
    this.maxLengthEnforcement,
    this.textAlign = TextAlign.start,
    this.autofocus = false,
    this.autocorrect = false,
    this.cursorWidth = 5.0,
    this.cursorHeight = 20.0,
    this.cursorRadius = const Radius.circular(10.0),
    this.keyboardType,
    this.style,
    this.textInputAction,
    this.strutStyle,
    this.textDirection,
    this.maxLength,
    this.onEditingComplete,
    this.onSubmitted,
    this.inputFormatters,
    this.cursorColor = AppThemeData.inputTextColor,
    this.keyboardAppearance,
    this.buildCounter,
    this.expands = false,
    this.minLines = 1,
    this.maxLines = 1,
    this.showCursor = true,
    this.onClick,
    this.onTapOutside,
    this.enableSuggestions = true,
    this.textAlignVertical,
    this.dragStartBehavior = DragStartBehavior.start,
    this.scrollController,
    this.scrollPhysics,
    this.selectionWidthStyle = BoxWidthStyle.tight,
    this.smartDashesType,
    this.smartQuotesType,
    this.selectionHeightStyle = BoxHeightStyle.tight,
    this.autofillHints,
    this.obscuringCharacter = '•',
    this.mouseCursor,
    this.magnifierConfiguration,
    this.contentInsertionConfiguration,
    this.spellCheckConfiguration,
    this.prefixText,
    this.prefixCode,
  }) : errorTextMessage = "".obs {
    // errorText = errorTextMessage.value;
  }

  void setText(String text) {
    controller!.text = text;
    markFieldAsValid();
  }

  void clear() {
    controller!.clear();
    markFieldAsValid();
  }

  void setError(String errorMessage) {
    inputErrorBorderColor.value = AppThemeData.inputErrorBorderColor;
    inputErrorColor.value = AppThemeData.inputErrorColor;
    errorTextMessage.value = errorMessage;
    isError.value = true;
  }

  void markFieldAsValid() {
    inputErrorBorderColor.value = AppThemeData.inputBackgroundColor;
    inputErrorColor.value = AppThemeData.inputErrorColor;
    errorTextMessage.value = "";
    isError.value = false;
  }

  void markFieldAsInvalid() {
    print("=============================");
    inputErrorBorderColor.value = AppThemeData.inputErrorBorderColor;
    inputErrorColor.value = AppThemeData.inputErrorColor;
    errorTextMessage.value = TranslationKeys.makeTranslation(TranslationKeys.textErrorRequired);
    isError.value = true;
  }

  void setDropDownOption(DropDown option) {
    selectedOption = Rx<DropDown>(option);
    setText(selectedOption!.value.label);
    markFieldAsValid();
  }

  bool validate(String value) {
    if (isRequired) {
      if (value.isEmpty) {
        markFieldAsInvalid();
        return false;
      }
      markFieldAsValid();
      return true;
    }
    markFieldAsValid();
    return true;
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(height: isTopMarginRequired ? 15 : 0),
          Visibility(
            visible: isBoxDecoration && showLabel,
            child: Column(
              children: [
                CustomText(labelText, style: AppThemeData.labelStyle),
                const SizedBox(height: 5),
              ],
            ),
          ),
          FormBuilderTextField(
            key: refKey,
            name: "",
            focusNode: focusNode,
            decoration: isCountryPicker ? countryCodeDecoration() : (isBoxDecoration ? boxedDecoration() : normalFieldDecoration()),
            enabled: enabled,
            autovalidateMode: autovalidateMode,
            restorationId: restorationId,
            readOnly: isDropDown ? true : readOnly,

            validator: (value) {
              validate(value!);
              return null;
            },
            onChanged: (value) {
              if (value!.isNotEmpty) {
                markFieldAsValid();
              }
              if (onChanged != null) {
                onChanged!(value);
              }
            },
            textCapitalization: textCapitalization,
            scrollPadding: scrollPadding,
            enableInteractiveSelection: enableInteractiveSelection,
            maxLengthEnforcement: maxLengthEnforcement,
            textAlign: textAlign,
            autofocus: isDropDown ? false : autofocus,
            autocorrect: autocorrect,
            keyboardType: keyboardType,
            style: AppThemeData.inputStyle.copyWith(height: 1, fontSize: double.parse((inputFontSize ?? "0.0").toString()) == 0 ? AppThemeData.inputStyle.fontSize : double.parse((inputFontSize ?? "0.0").toString()), fontWeight: inputFontWeight ?? AppThemeData.inputStyle.fontWeight, color: inputColor ?? AppThemeData.inputStyle.color),
            controller: controller,
            textInputAction: textInputAction ?? TextInputAction.done,
            strutStyle: strutStyle,
            textDirection: textDirection,
            maxLength: maxLength,
            onEditingComplete: onEditingComplete,
            onSubmitted: onSubmitted,
            inputFormatters: inputFormatters,
            cursorColor: cursorColor,
            // cursorWidth: 1.5,
            // cursorHeight: 15,
            // cursorRadius: Radius.circular(10.0),
            keyboardAppearance: keyboardAppearance,
            buildCounter: buildCounter,
            expands: expands,
            maxLines: isPassword ? maxLines = 1 : maxLines,
            obscureText: isPassword && _passwordVisible.value,
            minLines: isPassword ? minLines = 1 : minLines,
            showCursor: isDropDown ? false : showCursor,
            onTap: () {
              if (onClick != null) {
                onClick!();
              }
              if (isDropDown && items != null && items!.isNotEmpty) {
                //

                FocusScope.of(context).requestFocus(FocusNode());

                CustomDropDownBottomSheet().showBottomSheet(context, items!, dropDownType ?? DropDownType.NORMAL, (selectedItem) {
                  setText(selectedItem.label);
                  selectedOption = Rx<DropDown>(selectedItem);
                  if (onItemSelected != null) {
                    onItemSelected!(selectedItem);
                  }
                });
              }
            },
            onTapOutside: onTapOutside,
            enableSuggestions: enableSuggestions,
            textAlignVertical: textAlignVertical,
            dragStartBehavior: dragStartBehavior,
            scrollController: scrollController,
            scrollPhysics: scrollPhysics,
            selectionWidthStyle: selectionWidthStyle,
            smartDashesType: smartDashesType,
            smartQuotesType: smartQuotesType,
            selectionHeightStyle: BoxHeightStyle.tight,
            autofillHints: autofillHints,
            obscuringCharacter: obscuringCharacter,
            mouseCursor: mouseCursor,
            magnifierConfiguration: magnifierConfiguration,
            contentInsertionConfiguration: contentInsertionConfiguration,
            spellCheckConfiguration: spellCheckConfiguration,
          ),
        ],
      );
    });
  }

  InputDecoration normalFieldDecoration() {
    return InputDecoration(
      filled: true,
      prefixIcon: prefixIcon,
      fillColor: AppColors.transparent,
      isDense: true,
      contentPadding: const EdgeInsets.only(bottom: 5),
      labelText: labelText,
      labelStyle: AppThemeData.labelStyle,
      errorStyle: AppThemeData.errorStyle.copyWith(color: inputErrorColor.value),
      errorBorder: UnderlineInputBorder(borderSide: BorderSide(color: inputErrorBorderColor.value)),
      focusedBorder: const UnderlineInputBorder(borderSide: BorderSide(color: AppThemeData.inputFocusedBorderColor, width: 1.5)),
      enabledBorder: const UnderlineInputBorder(borderSide: BorderSide(color: AppThemeData.inputEnabledBorderColor, width: 1.5)),
      errorText: errorTextMessage.value.isEmpty ? null : errorTextMessage.value,
      hintText: hintText.isEmpty ? null : hintText,
      hintStyle: AppThemeData.hintStyle,
      prefixText: prefixText,
      prefixStyle: AppThemeData.hintStyle,
      suffixIcon: Icon(
        Icons.arrow_forward_ios_outlined,
        color: AppColors.colorGrey500,
        size: isDropDown ? 22 : 0,
      ),
    );
  }

  InputDecoration boxedDecoration() {
    return InputDecoration(
      isDense: true,
      contentPadding: contentPadding ?? const EdgeInsets.symmetric(horizontal: 15, vertical: 15) /*EdgeInsets.all(10)*/,
      labelText: isBoxDecoration ? null : (labelText.isNotEmpty ? labelText : null),
      labelStyle: AppThemeData.labelStyle,
      prefixIcon: prefixIcon,
      errorStyle: AppThemeData.errorStyle.copyWith(color: inputErrorColor.value),
      // border: OutlineInputBorder(borderSide: BorderSide(color: inputErrorBorderColor.value), borderRadius: BorderRadius.all(Radius.circular(10))),
      focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: inputErrorBorderColor.value), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      errorBorder: OutlineInputBorder(borderSide: BorderSide(color: inputErrorBorderColor.value), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      focusedBorder: OutlineInputBorder(borderSide: const BorderSide(color: AppThemeData.inputFocusedBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      enabledBorder: OutlineInputBorder(borderSide: const BorderSide(color: AppThemeData.inputEnabledBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      errorText: errorTextMessage.value.isEmpty ? null : errorTextMessage.value,
      hintText: hintText.isEmpty ? null : hintText,
      hintStyle: AppThemeData.hintStyle,
      prefixText: prefixText,
      // prefixStyle: AppThemeData.hintStyle,
      suffixIcon: suffixIcon ?? addSuffixIcon(),
    );
  }

  Widget? addSuffixIcon() {
    if (requiredPasswordIcon) {
      return IconButton(
        icon: Icon(size: 18, color: AppColors.colorGrey500, _passwordVisible.value ? Icons.visibility : Icons.visibility_off_rounded),
        onPressed: () {
          _passwordVisible.value = !_passwordVisible.value;
        },
      );
    } else if (isDropDown) {
      return const Icon(
        Icons.arrow_forward_ios_outlined,
        color: AppColors.colorGrey500,
        size: 22,
      );
    }
    return null;
  }

  InputDecoration countryCodeDecoration() {
    return InputDecoration(
      prefixIcon: CountryCodePicker(
        initialSelection: 'PK',
        onInit: (code) {
          selectedCountryCode.value = code!;
        },
        showFlagDialog: true,
        showCountryOnly: true,
        countryFilter: const [
          'pk',
          'us',
          'it',
        ],
        emptySearchBuilder: (context) {
          return Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              const SizedBox(height: 15),
              CustomText("No Results", style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.inputLabelColor)),
            ],
          );
        },
        onChanged: (val) {
          selectedCountryCode.value = val;
        },

        searchDecoration: InputDecoration(
          filled: false,
          fillColor: AppColors.transparent,
          isDense: false,
          alignLabelWithHint: true,
          contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
          errorStyle: AppThemeData.errorStyle.copyWith(color: AppThemeData.inputErrorColor),
          errorBorder: const OutlineInputBorder(borderSide: BorderSide(color: AppThemeData.inputErrorBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(10))),
          focusedBorder: const OutlineInputBorder(borderSide: BorderSide(color: AppThemeData.inputFocusedBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(10))),
          enabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: AppThemeData.inputEnabledBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(10))),
          prefixStyle: AppThemeData.hintStyle,
        ),
        searchStyle: AppThemeData.inputStyle.copyWith(height: 1),
        // textStyle: AppThemeData.inputStyle.copyWith(height: 1),
      ),
      isDense: true,
      contentPadding: const EdgeInsets.all(10),
      labelText: isBoxDecoration ? null : (labelText.isNotEmpty ? labelText : null),
      labelStyle: AppThemeData.labelStyle,
      errorStyle: AppThemeData.errorStyle.copyWith(color: inputErrorColor.value),
      focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: inputErrorBorderColor.value), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      errorBorder: OutlineInputBorder(borderSide: BorderSide(color: inputErrorBorderColor.value), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      focusedBorder: OutlineInputBorder(borderSide: const BorderSide(color: AppThemeData.inputFocusedBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      enabledBorder: OutlineInputBorder(borderSide: const BorderSide(color: AppThemeData.inputEnabledBorderColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(radius == -1 ? 10 : double.parse(radius.toString())))),
      // focusedErrorBorder: OutlineInputBorder(
      //     borderSide: BorderSide(color: inputErrorBorderColor.value),
      //     borderRadius: const BorderRadius.all(Radius.circular(10))),
      // errorBorder: OutlineInputBorder(
      //     borderSide: BorderSide(color: inputErrorBorderColor.value),
      //     borderRadius: const BorderRadius.all(Radius.circular(10))),
      // focusedBorder: const OutlineInputBorder(
      //     borderSide: BorderSide(
      //       color: AppThemeData.inputFocusedBorderColor,
      //       width: 1.5,
      //     ),
      //     borderRadius: BorderRadius.all(Radius.circular(10))),
      // enabledBorder: const OutlineInputBorder(
      //     borderSide: BorderSide(
      //         color: AppThemeData.inputEnabledBorderColor, width: 1.5),
      //     borderRadius: BorderRadius.all(Radius.circular(10))),
      errorText: errorTextMessage.value.isEmpty ? null : errorTextMessage.value,
      hintText: hintText.isEmpty ? null : hintText,
      hintStyle: AppThemeData.hintStyle,
      prefixText: prefixText ?? "",
      prefixStyle: AppThemeData.hintStyle,
      suffixIcon: Icon(
        Icons.arrow_forward_ios_outlined,
        color: AppColors.colorGrey500,
        size: isDropDown ? 22 : 0,
      ),
    );
  }

  String getCustomText({bool isCountryCodeRequired = false, bool isPrefixRequired = false}) {
    if (isCountryCodeRequired) {
      if (isCountryPicker) {
        return selectedCountryCode.value.dialCode! + controller!.text;
      }
      return controller!.text;
    } else if (isPrefixRequired) {
      return (prefixCode ?? "") + controller!.text;
    }
    return controller?.text ?? "";
  }
}

class DropDownType {
  static final String NORMAL = "01";
  static final String SPECIAL = "02";
}

class InputType {
  static final int INT_MAX_VALUE_ = 9223372036854775807;
  static final FilteringTextInputFormatter NUMBER = FilteringTextInputFormatter.allow(RegExp(r'[0-9.]'));
  static final FilteringTextInputFormatter NUMBER_DECIMAL = FilteringTextInputFormatter.allow(RegExp(r'^[0-9]*\.?[0-9]*$'));

  static List<TextInputFormatter> maxValueFilter(int maxNumber, bool isDecimal, int decimalPoint) {
    return [
      FilteringTextInputFormatter.allow(isDecimal ? RegExp(r'^\d+\.?\d{0,2}') : RegExp(r'^\d+$')),
      TextInputFormatter.withFunction((oldValue, newValue) {
        if (newValue.text.isEmpty) {
          return newValue.copyWith(text: '', selection: const TextSelection.collapsed(offset: 0));
        }
        try {
          final numericValue = double.parse(newValue.text);
          if (numericValue <= maxNumber) {
            return newValue;
          }
        } catch (e) {
          return newValue;
        }
        return oldValue;
      }),
    ];
  }
}
