import 'package:baseproject/core/common/utils.dart';
import 'package:baseproject/core/components/form/form_builder_field.dart';
import 'package:baseproject/core/language/app_localizations.dart';
import 'package:baseproject/core/theme/custom_color.dart';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';

// ignore: must_be_immutable
class CustomRadioList<T> extends FormBuilderField<T> {
  CustomRadioList({
    Key? key,
    String name = "radio",
    InputDecoration decoration = const InputDecoration(border: InputBorder.none, enabledBorder: InputBorder.none),
    T? initialValue,
    required this.items,
    this.propertyTitleName = "title",
    this.propertyIdName = "id",
    this.isReturnObject = true,
    this.padding = const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
    this.textStyle,
    this.scrollDirection = Axis.vertical,
    ValueChanged<T?>? onChanged,
    FormFieldValidator<T?>? validator,
    AutovalidateMode autovalidateMode = AutovalidateMode.disabled,
    this.nonTitleOddItem = false,
    this.enable = true,
    this.isTranslate = false,
    this.isSameLine = false,
    this.isHtmlText = false,
    this.isRowTitleHorizontal = false,
    this.answerTitles,
    this.scale = 1.0,
    this.selectedTextStyle,
    this.isShowDivider = false,
    this.isRunDidUpdate = false,
  }) : super(
          key: key,
          name: name,
          onChanged: onChanged,
          initialValue: initialValue,
          validator: validator,
          autovalidateMode: autovalidateMode,
          builder: (FormFieldState<T?> field) {
            final _CustomRadioListState<T> state = field as _CustomRadioListState<T>;
            return InputDecorator(
              decoration: decoration,
              child: state.buildBody(state.context),
            );
          },
        );

  final List<Object> items;
  final bool isReturnObject;
  final String propertyIdName;
  final String propertyTitleName;
  final EdgeInsets padding;
  final TextStyle? textStyle;
  final TextStyle? selectedTextStyle;
  final Axis scrollDirection;
  final bool isSameLine;
  final bool nonTitleOddItem;
  final bool enable;
  final bool isTranslate;
  final bool isHtmlText;
  final bool isRowTitleHorizontal;
  final List<Widget>? answerTitles;
  final double scale;
  final bool isShowDivider;
  final bool isRunDidUpdate;

  @override
  _CustomRadioListState<T> createState() => _CustomRadioListState<T>();
}

class _CustomRadioListState<T> extends FormBuilderFieldState<CustomRadioList<T>, T> {
  bool isShowSelect = false;
  Object? selectedValue;

  List<Object> get items => widget.items;

  //String title = "";
  EdgeInsets get padding => widget.padding;

  String get propertyIdName => widget.propertyIdName;
  bool isFirstLoad = true;
  double get radioSize => 18 * widget.scale;

  @override
  void initState() {
    super.initState();
    selectedValue = getItem();
    // print(selectedValue);
  }

  @override
  void didUpdateWidget(FormField<T?> oldWidget) {
    // selectedValue = getItem();
    super.didUpdateWidget(oldWidget);
    if (oldWidget.initialValue != widget.initialValue && widget.isRunDidUpdate) {
      setState(() {
        selectedValue = getItem();
      });
      didChange(widget.initialValue);
    }
  }

  TextStyle? getTextStyle(Object item) {
    if (selectedValue == item) {
      return widget.selectedTextStyle ?? widget.textStyle?.copyWith(fontWeight: FontWeight.w600);
    }
    return widget.textStyle;
  }

  List<Widget> _buildListItemHorizontal(Object item) {
    return [
      Container(
        width: radioSize,
        height: radioSize,
        margin: EdgeInsets.only(
          bottom: widget.isRowTitleHorizontal ? 0 : 6,
          right: widget.isRowTitleHorizontal ? 6 : 0,
        ),
        child: _buildRadio(item),
        // child: Transform.scale(
        //   scale: widget.scale,
        //   child: Radio<Object>(
        //     value: item,
        //     groupValue: selectedValue,
        //     onChanged: widget.enable ? (Object? value) => onChanged(value) : null,
        //   ),
        // ),
      ),
      if (items.indexOf(item) % 2 == 0 || !widget.nonTitleOddItem)
        // widget.isHtmlText
        //     ? TextHtmlWidget(widget.propertyTitleName)
        //     :
        Text(
          widget.isTranslate
              ? AppLocalizations.of(context)!
                  .translate(Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "")
              : Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "",
          style: widget.textStyle,
          textAlign: TextAlign.center,
        )
    ];
  }

  Widget buildBody(BuildContext context) {
    if (widget.scrollDirection == Axis.horizontal) {
      return Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          for (final Object item in items)
            Flexible(
              child: GestureDetector(
                onTap: widget.enable ? () => onChanged(item) : null,
                child: Container(
                  // padding: const EdgeInsets.only(right: 24),
                  color: Colors.transparent,
                  margin: items.indexOf(item) < items.length - 1 ? const EdgeInsets.only() : const EdgeInsets.all(0),
                  child: widget.isRowTitleHorizontal
                      ? Row(crossAxisAlignment: CrossAxisAlignment.center, children: _buildListItemHorizontal(item))
                      : Column(crossAxisAlignment: CrossAxisAlignment.center, children: _buildListItemHorizontal(item)),
                ),
              ),
            ),
        ],
      );
    }
    if (widget.isSameLine) {
      return SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            for (final Object item in items)
              GestureDetector(
                onTap: widget.enable ? () => onChanged(item) : null,
                child: Container(
                  color: Colors.white,
                  margin: items.indexOf(item) < items.length - 1
                      ? const EdgeInsets.only(right: 8)
                      : const EdgeInsets.all(0),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Container(
                        width: radioSize,
                        height: radioSize,
                        margin: const EdgeInsets.only(right: 8),
                        child: _buildRadio(item),
                        // Transform.scale(
                        //   scale: widget.scale,
                        //   child: Radio<Object>(
                        //     value: item,
                        //     groupValue: selectedValue,
                        //     onChanged: widget.enable ? (Object? value) => onChanged(value) : null,
                        //   ),
                        // ),
                      ),
                      // const SizedBox(width: 12),
                      Text(
                          widget.isTranslate
                              ? AppLocalizations.of(context)!
                                  .translate(Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "")
                              : Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "",
                          style: getTextStyle(item))
                    ],
                  ),
                ),
              ),
          ],
        ),
      );
    }
    return ListView.separated(
        shrinkWrap: true,
        itemBuilder: (context, index) {
          final Object item = items[index];
          return GestureDetector(
            onTap: widget.enable ? () => onChanged(item) : null,
            child: Container(
              color: Colors.transparent,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Container(
                    width: radioSize,
                    height: radioSize,
                    margin: const EdgeInsets.only(right: 8),
                    // child: Transform.scale(
                    //   scale: widget.scale,
                    //   child: Radio<Object>(
                    //     value: item,
                    //     groupValue: selectedValue,
                    //     onChanged: widget.enable ? (Object? value) => onChanged(value) : null,
                    //   ),
                    // ),
                    child: _buildRadio(item),
                  ),
                  widget.answerTitles != null
                      ? Expanded(child: widget.answerTitles![items.indexOf(item)])
                      // : widget.isHtmlText
                      //     ? Expanded(
                      //         child: TextHtmlWidget(
                      //         widget.isTranslate
                      //             ? AppLocalizations.of(context)!.translate(
                      //                 Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "")
                      //             : Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "",
                      //       ))
                      : Expanded(
                          child: Text(
                              widget.isTranslate
                                  ? AppLocalizations.of(context)!.translate(
                                      Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "")
                                  : Utils.getPropertyValueByName<String>(item, widget.propertyTitleName) ?? "",
                              style: getTextStyle(item)),
                        )
                ],
              ),
            ),
          );
        },
        separatorBuilder: (context, index) => Padding(
              padding: EdgeInsets.symmetric(vertical: widget.isShowDivider ? 7 : 10),
              child: widget.isShowDivider ? const Divider() : const SizedBox(),
            ),
        itemCount: items.length);
  }

  // void changeTitle() {
  //   title = Utils.getPropertyValueByName<String>(
  //           selectedValue, widget.propertyTitleName) ??
  //       "";
  // }

  Widget _buildRadio(Object item) {
    bool selected = selectedValue != null && getValue(selectedValue) == getValue(item); //item[propertyIdName];
    return InkWell(
      onTap: () => onChanged(item),
      child: Container(
        width: radioSize,
        height: radioSize,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: selected ? CustomColor.primaryColor : Colors.transparent,
          border: Border.all(
            color: selected ? CustomColor.primaryColor : CustomColor.textGray,
            width: 1.0,
          ),
        ),
        child: selected
            ? Center(
                child: Container(
                  width: radioSize * 0.4,
                  height: radioSize * 0.4,
                  decoration: const BoxDecoration(
                    shape: BoxShape.circle,
                    color: Colors.white,
                  ),
                ),
              )
            : null,
      ),
    );
  }

  void onChanged(Object? data, {bool isFirstLoad = false}) {
    if (selectedValue == data) {
      return;
    }
    if (!isFirstLoad) {
      setState(() {
        selectedValue = data; //changeTitle();
      });
    }

    final T? temp = getValue(data);
    didChange(temp);
  }

  T? getValue(Object? data) {
    if (widget.isReturnObject) {
      return data as T?;
    } else {
      final T? value = Utils.getPropertyValueByName<T>(data, propertyIdName);
      return value;
    }
  }

  Object? getItem() {
    print(initialValue);
    Map<String, dynamic> temp;
    if (widget.isReturnObject && initialValue != null) {
      return initialValue;
    } else if (propertyIdName.isNotEmpty && initialValue != null) {
      return items.firstWhereOrNull((Object element) {
        if (element == null) return false;
        temp = Utils.convertObjectToMap(element);
        return temp[propertyIdName] == initialValue;
      });
    }
    return null;
  }
}
