// ignore_for_file: non_constant_identifier_names

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:general_package/dynamic_form/dynamic_form.dart';
import 'package:general_package/enum_to_string/enum_to_string.dart';

bool boolFromInt(int done) => done == 1;

enum DynamicFormFieldTypeEnum {
  text,
  email,
  phoneNumber,
  password,
  radio,
  radioModern,
  dropdown,
  date,
  time,
  dateTime,
  dateRange,
  dateTimeRange,
  rangeSlider,
  switchInput,
  checkbox,
  segmented,
  chipsSingle,
  chipsMultiple,
  timeSlot,
  tab,
  valueAddService,
  connectors,
  dateSlider,
  otp,
  multipleImageUpload,
  singleImageUpload,
  rating
}

class ValueAddService {
  int id;
  String title;
  String description;
  String price;
  String value;
  bool isChecked;

  ValueAddService({
    required this.id,
    required this.title,
    required this.description,
    required this.price,
    required this.value,
    required this.isChecked,
  });

  static Map<String, dynamic> toMap(ValueAddService form) {
    var map = <String, dynamic>{};
    map['id'] = form.id;
    map['title'] = form.title;
    map['description'] = form.description;
    map['price'] = form.price;
    map['value'] = form.value;
    map['isChecked'] = form.isChecked;
    return map;
  }

  factory ValueAddService.fromJson(dynamic json) {
    return ValueAddService(
      id: json['id'],
      title: json['title'],
      description: json['description'],
      price: json['price'],
      value: json['value'],
      isChecked: json['isChecked'],
    );
  }
}

class Connectors {
  late int id;
  late int subscriptionId;
  late String adapterName;
  late int adapterId;
  late String adapterModel;
  late int plugPinPoints;
  late String adapterDescription;
  late String dispesingUnits;
  late String price;
  late dynamic value;
  late bool isChecked;

  Connectors(
      {required this.id,
      required this.subscriptionId,
      required this.adapterName,
      required this.adapterId,
      required this.adapterModel,
      required this.plugPinPoints,
      required this.adapterDescription,
      required this.dispesingUnits,
      required this.price,
      required this.value,
      required this.isChecked});

  Connectors.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    subscriptionId = json['subscriptionId'];
    adapterName = json['adapterName'];
    adapterId = json['adapterId'];
    adapterModel = json['adapterModel'];
    plugPinPoints = json['plugPinPoints'];
    adapterDescription = json['adapterDescription'];
    dispesingUnits = json['dispesingUnits'];
    price = json['price'];
    value = json['value'];
    isChecked = json['isChecked'];
  }

  static Map<String, dynamic> toJson(Connectors  connector) {
    final Map<String, dynamic> data = {};
    data['id'] = connector.id;
    data['subscriptionId'] = connector.subscriptionId;
    data['adapterName'] = connector.adapterName;
    data['adapterId'] = connector.adapterId;
    data['adapterModel'] = connector.adapterModel;
    data['plugPinPoints'] = connector.plugPinPoints;
    data['adapterDescription'] = connector.adapterDescription;
    data['dispesingUnits'] = connector.dispesingUnits;
    data['price'] = connector.price;
    data['value'] = connector.value;
    data['isChecked'] = connector.isChecked;
    return data;
  }
}


class FieldCondition {
  int conditionFieldId;
  String conditionFieldName;
  String equalValue;
  String fieldIdType;
  String equalValueType;

  FieldCondition({
    required this.conditionFieldId,
    required this.conditionFieldName,
    required this.equalValue,
    required this.fieldIdType,
    required this.equalValueType,
  });

  static Map<String, dynamic> toMap(FieldCondition form) {
    var map = <String, dynamic>{};
    map['conditionFieldId'] = form.conditionFieldId;
    map['conditionFieldName'] = form.conditionFieldName;
    map['equalValue'] = form.equalValue;
    map['fieldIdType'] = form.fieldIdType;
    map['equalValueType'] = form.equalValueType;
    return map;
  }

  factory FieldCondition.fromJson(dynamic json) {
    return FieldCondition(
      conditionFieldId: json['conditionFieldId'],
      conditionFieldName: json['conditionFieldName'],
      equalValue: json['equalValue'],
      fieldIdType: json['fieldIdType'],
      equalValueType: json['equalValueType'],
    );
  }
}

class DateFieldCondition {
  int conditionFieldId;
  String conditionFieldName;
  bool? greaterThanValue;
  bool? lesserThanValue;

  DateFieldCondition({
    required this.conditionFieldId,
    required this.conditionFieldName,
    this.greaterThanValue,
    this.lesserThanValue,
  });

  static Map<String, dynamic> toMap(DateFieldCondition form) {
    var map = <String, dynamic>{};
    map['conditionFieldId'] = form.conditionFieldId;
    map['conditionFieldName'] = form.conditionFieldName;
    map['greaterThanValue'] = form.greaterThanValue;
    map['lesserThanValue'] = form.lesserThanValue;
    return map;
  }

  factory DateFieldCondition.fromJson(dynamic json) {
    return DateFieldCondition(
      conditionFieldId: json['conditionFieldId'],
      conditionFieldName: json['conditionFieldName'],
      greaterThanValue: json['greaterThanValue'],
      lesserThanValue: json['lesserThanValue'],
    );
  }
}

class DynamicFormFieldModel {
  int id;
  String name;
  String? title;
  bool visible = true;
  bool readOnly;
  String? placeHolder;
  double? padding;
  bool? isRequired = false;
  dynamic value;
  int? divisions;
  double? max;
  double? min;
  List<dynamic>? option;
  DynamicFormFieldTypeEnum type;
  List<String>? tabsMenu;
  List<List<DynamicFormFieldModel>>? inputs;
  List<ValueAddService>? valueAddService;
  List<Connectors>? connectors;

  int? dateSliderCount;
  DynamicFormButtonModel? resendOTPButton;
  List<DynamicFormFieldModel>? filesUpload;
  FieldCondition? onCondition;
  DateFieldCondition? onConditionForDate;

  DynamicFormFieldModel({
    required this.name,
    required this.id,
    required this.title,
    required this.type,
    required this.visible,
    required this.readOnly,
    this.padding,
    this.isRequired,
    this.placeHolder,
    this.value,
    this.option,
    this.tabsMenu,
    this.inputs,
    this.valueAddService,
    this.connectors,
    this.dateSliderCount,
    this.resendOTPButton,
    this.filesUpload,
    this.onCondition,
    this.onConditionForDate,
  });

  static Map<String, dynamic> toMap(DynamicFormFieldModel form) {
    var map = <String, dynamic>{};
    map['id'] = form.id;
    map['name'] = form.name;
    map['title'] = form.title;
    map['placeHolder'] = form.placeHolder;
    map['padding'] = form.padding;
    map['type'] = EnumToString.convertToString(form.type);
    map['value'] = form.value;
    map['isRequired'] = form.isRequired;
    map['value'] = form.value;
    map['option'] = form.option;
    map['connectors'] = form.connectors != null
        ? form.connectors!.map((e) => Connectors.toJson(e)).toList()
        : null;
    map['resendOTPButton'] = form.resendOTPButton;
    return map;
  }

  factory DynamicFormFieldModel.fromJson(dynamic json) {
    // (json['inputs'] != null)? json['inputs'].map<List<List<DynamicFormFieldModel>>>((DynamicFormFieldInputsList) => DynamicFormFieldInputsList.map<List<DynamicFormFieldModel>>((DynamicFormFieldInputs)=> DynamicFormFieldInputs.map<DynamicFormFieldModel>((dynamicFormFieldInput)=>DynamicFormFieldModel.fromJson(dynamicFormFieldInput)).toList()).toList).toList() :

    // json['inputs'].map((DynamicFormFieldInputsList) {
    //   DynamicFormFieldInputsList.map((DynamicFormFieldInputs) {
    //     print(DynamicFormFieldInputs);
    //     // var dummy = DynamicFormFieldModel(id: 1,name: "hours_booking_start",type: DynamicFormFieldTypeEnum.date,title: "Select start Date", placeHolder: "Select start Date",visible: true, readOnly: false);
    //     try{

    //     }catch(e){
    //       print(e);
    //     }
    //   }).toList();
    // }).toList();

    // json['inputs'].map<List<List<DynamicFormFieldModel>>>((DynamicFormFieldInputsList) {
    //         print(DynamicFormFieldInputsList);
    //     return DynamicFormFieldInputsList.map<List<DynamicFormFieldModel>>((DynamicFormFieldInputs){
    //         print(DynamicFormFieldInputs);
    //       return DynamicFormFieldInputs.map<DynamicFormFieldModel>((dynamicFormFieldInput) {
    //         print(dynamicFormFieldInput);
    //         return DynamicFormFieldModel.fromJson(dynamicFormFieldInput);
    //       }).toList();
    //     }
    //   ).toList();
    // }).toList();
    List<List<DynamicFormFieldModel>> inputsList = [];
    if (json["inputs"] != null) {
      json["inputs"].map<List<List<DynamicFormFieldModel>>>((data) {
        List<DynamicFormFieldModel> dummy2 = [];
        List<dynamic> mapData = data;
        mapData.map((data2) {
          var dynamicFormFieldModelData = DynamicFormFieldModel.fromJson(data2);
          print(dynamicFormFieldModelData.name);
          dummy2.add(dynamicFormFieldModelData);
        }).toList();
        inputsList.add(dummy2);
        print(inputsList.length);
        return inputsList;
      }).toList();
    }
    return DynamicFormFieldModel(
      id: json['id'] ?? 0,
      name: json['name'],
      title: json['title'],
      visible: json['visible'] ?? true,
      readOnly: json['readOnly'] ?? false,
      placeHolder: json['placeHolder'],
      padding: json['padding'],
      type: EnumToString.fromString(
              DynamicFormFieldTypeEnum.values, json['type']) ??
          DynamicFormFieldTypeEnum.text,
      value: json['value'],
      option: (json['option'] != null)
          ? List<dynamic>.from(json['option'] as List)
          : null,
      isRequired: json['isRequired'],
      tabsMenu: (json['tabMenu'] != null)
          ? List<String>.from(json['tabMenu'] as List)
          : null,
      // inputs: (json['inputs'] != null)
      //     ? json['inputs']
      //         .map<List<List<DynamicFormFieldModel>>>((DynamicFormFieldInputsList) => DynamicFormFieldInputsList.map(
      //                 (DynamicFormFieldInputs) =>
      //                     DynamicFormFieldModel.fromJson(DynamicFormFieldInputs))
      //             .toList())
      //         .toList()
      //     : null,
      inputs: inputsList,
      valueAddService: (json['valueAddService'] != null)
          ? json['valueAddService']
              .map((valueAddService) =>
                  ValueAddService.fromJson(valueAddService))
              .toList()
          : null,
      connectors: (json['connectors'] != null)
          ? json['connectors']
              .map<Connectors>((connector) => Connectors.fromJson(connector))
              .toList()
          : null,
      dateSliderCount: json["dateSliderCount"],
      resendOTPButton: (json['resendOtpButton'] != null)
          ? DynamicFormButtonModel.fromJson(json["resendOtpButton"])
          : null,
      filesUpload: (json['filesUpload'] != null)
          ? json['filesUpload']
              .map<DynamicFormFieldModel>(
                  (filesUpload) => DynamicFormFieldModel.fromJson(filesUpload))
              .toList()
          : null,
      onCondition: (json['onCondition'] != null)
          ? FieldCondition.fromJson(json['onCondition'])
          : null,
      onConditionForDate: (json['onConditionForDate'] != null)
          ? DateFieldCondition.fromJson(json['onConditionForDate'])
          : null,
    );
  }
}

enum DynamicFormButtonTypeEnum { bg, boarder, text }

enum DynamicFormButtonOnPressEnum {
  postData,
  backPage,
  movePage,
  scanAndPostData,
  disable,
}

class DynamicFormButtonModel {
  int id;
  String? onSubmit;
  // String name;
  String title;
  DynamicFormButtonTypeEnum type;
  DynamicFormButtonOnPressEnum onPressed;
  EdgeInsetsGeometry? padding;
  double? width;
  bool? isDisabled = false;
  Color? backgroundColor;
  Color? foregroundColor;
  Color? color;
  double? borderRadius;
  double? fontSize;
  FontWeight? fontWeight;
  double? elevation;
  Map<String, dynamic> postData;

  DynamicFormButtonModel({
    this.onSubmit,
    required this.id,
    // required this.name,
    required this.type,
    required this.title,
    required this.onPressed,
    required this.postData,
    this.isDisabled,
    this.padding,
    this.width,
    this.backgroundColor,
    this.foregroundColor,
    this.color,
    this.borderRadius,
    this.fontSize,
    this.fontWeight,
    this.elevation,
  });
  static Map<String, dynamic> toMap(DynamicFormButtonModel form) {
    var map = <String, dynamic>{};
    map['onSubmit'] = form.onSubmit;
    map['id'] = form.id;
    // map['name'] = form.name;
    map['type'] = EnumToString.convertToString(form.type);
    map['onPressed'] = EnumToString.convertToString(form.onPressed);
    map['title'] = form.title;
    map['padding'] = form.padding;
    map['width'] = double.parse(form.width.toString());
    map['backgroundColor'] = form.backgroundColor;
    map['foregroundColor'] = form.foregroundColor;
    map['color'] = form.color;
    map['fontSize'] = form.fontSize;
    map['fontWeight'] = form.fontWeight;
    map['elevation'] = form.elevation;
    return map;
  }

  factory DynamicFormButtonModel.fromJson(dynamic json) {
    // var dummy={};
    //   Map.from(json).forEach((key, value) {
    //     if(value==null){
    //       dummy.addAll({key:value});
    //     }
    //   });
    //  List newList = dummy.keys.toList();
    //  print(newList);
    return DynamicFormButtonModel(
      id: json['id'] ?? 0,
      // name: json['name'],
      type: EnumToString.fromString(
              DynamicFormButtonTypeEnum.values, json['type']) ??
          DynamicFormButtonTypeEnum.bg,
      title: json['title'],
      onPressed: json['onPressed'] != null
          ? EnumToString.fromString(
                  DynamicFormButtonOnPressEnum.values, json['onPressed']) ??
              DynamicFormButtonOnPressEnum.postData
          : DynamicFormButtonOnPressEnum.postData,
      padding: json['padding'] != null
          ? EdgeInsets.all(double.parse(json['padding'].toString()))
          : null,
      width:
          json['width'] != null ? double.parse(json['width'].toString()) : null,
      backgroundColor: json['backgroundColor'],
      foregroundColor: json['foregroundColor'],
      isDisabled: json['isDisabled'] ?? false,
      color: json['color'],
      fontSize: json['fontSize'],
      fontWeight: json['fontWeight'],
      elevation: json['elevation'],
      postData: json['postData'] ?? {},
      onSubmit: json['onSubmit'],
    );
  }
}

class DynamicFromSectionModel {
  int sectionId;
  String? title;
  String? subTitle;
  String? prefixTitle;
  Color? prefixTitleColor;
  List<DynamicFormFieldModel> fields;
  DynamicFromSectionModel({
    required this.sectionId,
    this.title,
    this.subTitle,
    this.prefixTitle,
    this.prefixTitleColor,
    required this.fields,
  });

  static Map<String, dynamic> toMap(DynamicFromSectionModel form) {
    var map = <String, dynamic>{};
    map['sectionId'] = form.sectionId;
    map['title'] = form.title;
    map['subTitle'] = form.subTitle;
    map['prefixTitle'] = form.prefixTitle;
    map['prefixTitleColor'] = form.prefixTitleColor;
    map['fields'] = form.fields;
    return map;
  }

  factory DynamicFromSectionModel.fromJson(dynamic json) {
    List<DynamicFormFieldModel> sectionFields = [];
    for (var element in json["fields"]) {
      sectionFields.add(DynamicFormFieldModel.fromJson(element));
    }
    return DynamicFromSectionModel(
      sectionId: json['sectionId'],
      title: json['title'],
      subTitle: json['subTitle'],
      prefixTitle: json['prefixTitle'],
      prefixTitleColor: json['prefixTitleColor'],
      fields: sectionFields,
    );
  }
}

class DynamicFormModel {
  // int id;
  String slug;
  String? title;
  String? description;
  bool isBackButton;
  String? image;
  double? imageWidth;
  double? imageHeight;
  String? bottomImage;
  double? bottomImageWidth;
  double? bottomImageHeight;
  List<DynamicFormFieldModel> fields;
  List<DynamicFromSectionModel> sections;
  List<DynamicFormButtonModel> buttons;

  DynamicFormModel({
    // required this.id,
    required this.slug,
    this.title,
    this.description,
    this.isBackButton = false,
    this.bottomImage,
    this.bottomImageWidth,
    this.bottomImageHeight,
    this.image,
    this.imageWidth,
    this.imageHeight,
    required this.fields,
    required this.sections,
    required this.buttons,
  });

  factory DynamicFormModel.fromJson(dynamic json) {
    debugPrint("$json - DynamicFormModel");
    List<DynamicFormFieldModel> fields = [];
    for (var element in json["fields"] ?? []) {
      fields.add(DynamicFormFieldModel.fromJson(element));
      try {
        // fields.add(DynamicFormFieldModel.fromJson(element));
      } catch (e) {
        if (kDebugMode) {
          debugPrint("$e - Error on fields - ${element['name']}");
        }
      }
    }
    List<DynamicFromSectionModel> sections = [];
    for (var element in json["sections"] ?? []) {
      try {
        sections.add(DynamicFromSectionModel.fromJson(element));
      } on Exception catch (e) {
        if (kDebugMode) {
          debugPrint("$e - Error on sections");
        }
      }
    }

    List<DynamicFormButtonModel> buttons = [];
    for (var element in json["buttons"] ?? []) {
      try {
        buttons.add(DynamicFormButtonModel.fromJson(element));
      } catch (e) {
        if (kDebugMode) {
          debugPrint("$e - Error on buttons");
        }
      }
    }
    buttons = buttons.map<DynamicFormButtonModel>((element) {
      if (element.onPressed == DynamicFormButtonOnPressEnum.postData) {
        fields.map((e) {
          if (e.value != null) {
            element.postData.addAll({e.name: e.value});
          }
        }).toList();
      }
      return element;
    }).toList();

    return DynamicFormModel(
        // id: json['id'],
        slug: json['slug'],
        title: json['title'],
        description: json['description'],
        isBackButton: json['isBackButton'],
        image: json['image'],
        imageWidth: json['imageWidth'],
        imageHeight: json['imageHeight'],
        bottomImage: json['bottomImage'],
        bottomImageWidth: json['bottomImageWidth'],
        bottomImageHeight: json['bottomImageHeight'],
        fields: fields,
        sections: sections,
        buttons: buttons);
  }
}
