import 'dart:convert';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:hub/components/templates_components/details_component/details_component_widget.dart';
import 'package:hub/features/backend/index.dart';
import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/flutter_flow_widgets.dart';
import 'package:hub/flutter_flow/form_field_controller.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/pets_page/pets_page_widget.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/image_util.dart';
import 'package:hub/shared/utils/limited_text_size.dart';
import 'package:hub/shared/utils/validator_util.dart';

class PetsPageModel extends FlutterFlowModel<PetsPageWidget> {
  PetsPageModel({
    required this.isInteractive,
  });
  late final bool isInteractive;

  late String devUUID = '';
  late String userUUID = '';
  late String cliUUID = '';
  late String petAmountRegister = '0';
  dynamic item;

  late final TabController tabBarController;
  VoidCallback? onUpdatePet;
  VoidCallback? onRegisterPet;
  VoidCallback? safeSetState;
  VoidCallback? updateImage;

  final GlobalKey<FormState> registerFormKey = GlobalKey<FormState>();
  final GlobalKey<FormState> updateFormKey = GlobalKey<FormState>();

  ApiCallResponse? petsResponse;
  int? petId;
  BuildContext? buildContext;
  bool isEditing = false;

  bool isDataUploading = false;
  FFUploadedFile? uploadedLocalFile;
  FFUploadedFile? uploadedTempFile;
  String? imgBase64;

  late String defaultDropDownText = '';

  String? dropDownValue1;
  FormFieldController<String>? dropDownValueController1;

  String? dropDownValue2;
  FormFieldController<String>? dropDownValueController2;

  FocusNode? textFieldFocusName;
  TextEditingController? textControllerName;
  String? textControllerNameValidator(BuildContext context, String? val) {
    if (val == null || val.isEmpty) {
      return FFLocalizations.of(context).getVariableText(
        enText: 'This field is required',
        ptText: 'Este campo é obrigatório',
      );
    }
    return null;
  }

  FocusNode? textFieldFocusSpecies;
  TextEditingController? textControllerSpecies;
  String? textControllerSpeciesValidator(BuildContext context, String? val) {
    if (val == null || val.isEmpty) {
      return FFLocalizations.of(context).getVariableText(
        enText: 'This field is required',
        ptText: 'Este campo é obrigatório',
      );
    }
    return null;
  }

  FocusNode? textFieldFocusRace;
  TextEditingController? textControllerRace;
  String? textControllerRaceValidator(BuildContext context, String? val) {
    if (val == null || val.isEmpty) {
      return FFLocalizations.of(context).getVariableText(
        enText: 'This field is required',
        ptText: 'Este campo é obrigatório',
      );
    }
    return null;
  }

  FocusNode? textFieldFocusColor;
  TextEditingController? textControllerColor;
  String? Function(BuildContext, String?)? textControllerColorValidator;

  DateTime? selectedDate;
  FocusNode? textFieldFocusData;
  TextEditingController? textControllerData;
  String? textControllerDataValidator(BuildContext context, String? val) {
    return null;
  }

  FocusNode? textFieldFocusObservation;
  TextEditingController? textControllerObservation;
  String? Function(BuildContext, String?)? textControllerObservationValidator;

  Future<void> initAsync() async {
    defaultDropDownText =
        FFLocalizations.of(navigatorKey.currentContext!).getVariableText(
      enText: 'Select an option',
      ptText: 'Selecione uma opção',
    );
    dropDownValueController1 =
        FormFieldController<String>(dropDownValue1 ??= defaultDropDownText);
    dropDownValueController2 =
        FormFieldController<String>(dropDownValue2 ??= defaultDropDownText);

    safeSetState?.call();
  }

  @override
  void initState(BuildContext context) {
    initAsync();
    tabBarController = TabController(
      vsync: Navigator.of(context),
      length: 2,
    );

    textFieldFocusName = FocusNode();
    textControllerName = TextEditingController();

    textFieldFocusSpecies = FocusNode();
    textControllerSpecies = TextEditingController();

    textFieldFocusRace = FocusNode();
    textControllerRace = TextEditingController();

    textFieldFocusColor = FocusNode();
    textControllerColor = TextEditingController();

    textFieldFocusData = FocusNode();
    textControllerData = TextEditingController(text: '');

    textFieldFocusObservation = FocusNode();
    textControllerObservation = TextEditingController();

    WidgetsBinding.instance.addPostFrameCallback((_) async {
      devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
      userUUID =
          await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? '';
      cliUUID =
          await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? '';
      petAmountRegister =
          await StorageHelper().get(LocalsStorageKey.petAmount.key) ?? '';
    });
  }

  void setEditForm() {
    if (item != null) petId = item['id'];

    // updateImage!();
    (() async {
      Response response = await get(Uri.parse(
          'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'));
      String base64 = base64Encode(response.bodyBytes);
      uploadedTempFile = await ImageUtils.convertToUploadFile(base64);
      updateImage?.call();
    })();

    textControllerName =
        TextEditingController(text: item != null ? item['name'] ?? '' : '');
    textFieldFocusName = FocusNode();

    textControllerSpecies =
        TextEditingController(text: item != null ? item['species'] ?? '' : '');
    textFieldFocusSpecies = FocusNode();

    textControllerRace =
        TextEditingController(text: item != null ? item['breed'] ?? '' : '');
    textFieldFocusRace = FocusNode();

    textControllerColor =
        TextEditingController(text: item != null ? item['color'] ?? '' : '');
    textFieldFocusColor = FocusNode();

    textControllerData = TextEditingController(
        text: item != null
            ? item['birthdayDate'] != null
                ? ValidatorUtil.formatDateTimePicker(item['birthdayDate'])
                : ''
            : '');

    textFieldFocusData = FocusNode();

    textControllerObservation =
        TextEditingController(text: item != null ? item['notes'] ?? '' : '');
    textFieldFocusObservation = FocusNode();

    item != null ? dropDownValue1 = item['gender'] ?? '' : dropDownValue1 = '';
    item != null ? dropDownValue2 = item['size'] ?? '' : dropDownValue2 = '';

    dropDownValueController1 = FormFieldController<String>(dropDownValue1);
    dropDownValueController2 = FormFieldController<String>(dropDownValue2);
  }

  @override
  void dispose() {
    tabBarController.dispose();

    textFieldFocusName?.dispose();
    textControllerName?.dispose();

    textFieldFocusSpecies?.dispose();
    textControllerSpecies?.dispose();

    textFieldFocusRace?.dispose();
    textControllerRace?.dispose();

    textFieldFocusColor?.dispose();
    textControllerColor?.dispose();

    textFieldFocusData?.dispose();
    textControllerData?.dispose();

    textFieldFocusObservation?.dispose();
    textControllerObservation?.dispose();

    dropDownValueController1?.dispose();
    dropDownValueController2?.dispose();
  }

  bool isFormValid(BuildContext context) {
    if (uploadedLocalFile == null || uploadedLocalFile!.bytes!.isEmpty) {
      return false;
    }
    if (textControllerName.text.isEmpty ||
        textControllerName.text.length > 80 ||
        textControllerName.text == '') {
      return false;
    }
    if (textControllerSpecies.text.isEmpty ||
        textControllerSpecies.text == '') {
      return false;
    }
    if (textControllerRace.text.isEmpty || textControllerRace.text == '') {
      return false;
    }

    if (dropDownValueController1!.value == defaultDropDownText ||
        dropDownValueController1!.value == '' ||
        dropDownValueController1!.value == null) {
      return false;
    }
    if (dropDownValueController2!.value == defaultDropDownText ||
        dropDownValueController2!.value == '' ||
        dropDownValueController2!.value == null) {
      return false;
    }

    if (dropDownValue1 == 'Selecione uma opção' ||
        dropDownValue1 == null ||
        dropDownValue1 == '') {
      return false;
    }

    if (dropDownValue2 == 'Selecione uma opção' ||
        dropDownValue2 == null ||
        dropDownValue2 == '') {
      return false;
    }

    return true;
  }

  Future<void> updatePet() async {
    var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!);
    img = "base64;jpeg,$img";
    final url =
        'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId';
    final response = await PhpGroup.updatePet.call(
      petID: petId,
      image: img,
      birthdayDate: textControllerData!.text,
      color: textControllerColor!.text,
      breed: textControllerRace!.text,
      species: textControllerSpecies!.text,
      name: textControllerName!.text,
      gender: dropDownValue1!,
      notes: textControllerObservation!.text,
      size: dropDownValue2!,
    );

    if (response.jsonBody['error'] == false) {
      await DialogUtil.success(
        buildContext!,
        FFLocalizations.of(buildContext!).getVariableText(
          enText: 'Pet successfully updated',
          ptText: 'Pet atualizado com sucesso',
        ),
      ).then((_) async {
        CachedNetworkImage.evictFromCache(url);
        switchTab(1);
      });
      onUpdatePet?.call();
    } else {
      String errorMessage;
      try {
        errorMessage =
            jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString();
      } catch (e) {
        errorMessage = FFLocalizations.of(buildContext!).getVariableText(
          enText: 'Failed to update pet',
          ptText: 'Falha ao atualizar o pet',
        );
      }
      await DialogUtil.error(buildContext!, errorMessage);
    }
  }

  Future<void> registerPet() async {
    var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!);
    img = "base64;jpeg,$img";
    final response = await PhpGroup.registerPet.call(
      image: img,
      birthdayDate: textControllerData!.text,
      color: textControllerColor!.text,
      breed: textControllerRace!.text,
      species: textControllerSpecies!.text,
      name: textControllerName!.text,
      gender: dropDownValue1!,
      size: dropDownValue2!,
      notes: textControllerObservation!.text,
    );

    if (response.jsonBody['error'] == false) {
      await DialogUtil.success(
        buildContext!,
        FFLocalizations.of(buildContext!).getVariableText(
          enText: 'Pet successfully registered',
          ptText: 'Pet cadastrado com sucesso',
        ),
      );
      onRegisterPet?.call();
    } else {
      String errorMessage;
      try {
        errorMessage =
            jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString();
        await DialogUtil.error(buildContext!, errorMessage);
      } catch (e) {
        if (response.jsonBody['error_msg'] ==
            "Limite de Cadastro de Pet Atingido.") {
          errorMessage = FFLocalizations.of(buildContext!).getVariableText(
            enText: 'Pet registration limit reached',
            ptText: 'Limite de cadastro de pets atingido',
          );
          await DialogUtil.error(buildContext!, errorMessage);
        } else {
          await DialogUtil.errorDefault(buildContext!);
        }
      }
    }
  }

  void switchTab(int index) {
    tabBarController.animateTo(index);
    if (index == 1) handleEditingChanged(false);
    safeSetState?.call();
  }

  void handleUploadComplete(FFUploadedFile uploadedFile) {
    uploadedLocalFile = uploadedFile;
    safeSetState?.call();
  }

  void handleEditingChanged(bool editing) {
    isEditing = editing;
    clearFields();
  }

  void clearFields() async {
    uploadedLocalFile = null;

    textControllerName = TextEditingController(text: '');
    textControllerSpecies = TextEditingController(text: '');
    textControllerRace = TextEditingController(text: '');
    textControllerColor = TextEditingController(text: '');
    textControllerObservation = TextEditingController(text: '');

    // textControllerData = TextEditingController(
    //     text: dateTimeFormat(
    //   'dd/MM/yyyy',
    //   DateTime.now(),
    // ));

    // dropDownValue1 = '';
    // dropDownValue2 = '';

    // dropDownValueController1 = FormFieldController<String>('Selecione uma opção');
    // dropDownValueController2 = FormFieldController<String>('Selecione uma opção');
  }

  Widget buildPetDetails({
    required dynamic item,
    required BuildContext context,
    required String devUUID,
    required String userUUID,
    required String cliUUID,
    required String cliName,
    required PetsPageModel model,
  }) {
    return DetailsComponentWidget(
      buttons: isInteractive
          ? [
              FFButtonWidget(
                text: FFLocalizations.of(context).getVariableText(
                  ptText: 'Editar',
                  enText: 'Edit',
                ),
                icon: const Icon(Icons.edit),
                onPressed: () async {
                  context.pop();

                  model.isEditing = true;
                  model.item = item;
                  model.switchTab(0);
                  model.setEditForm();
                  // model.safeSetState!();
                },
                options: FFButtonOptions(
                  height: 40,
                  color: FlutterFlowTheme.of(context).primaryBackground,
                  elevation: 0,
                  textStyle: TextStyle(
                    color: FlutterFlowTheme.of(context).primaryText,
                    fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15),
                  ),
                  splashColor: const Color.fromARGB(95, 0, 146, 5),
                  borderSide: BorderSide(
                    color: FlutterFlowTheme.of(context).primaryBackground,
                    width: 1,
                  ),
                  // borderRadius: 12,
                ),
              ),
              FFButtonWidget(
                text: FFLocalizations.of(context).getVariableText(
                  ptText: 'Excluir',
                  enText: 'Delete',
                ),
                icon: const Icon(Icons.close),
                onPressed: () async {
                  showAlertDialog(
                      context,
                      FFLocalizations.of(context).getVariableText(
                        ptText: 'Excluir Pet',
                        enText: 'Delete Pet',
                      ),
                      FFLocalizations.of(context).getVariableText(
                        ptText: 'Você tem certeza que deseja excluir esse pet?',
                        enText: 'Are you sure you want to delete this pet?',
                      ), () async {
                    int id = item['id'];
                    await PhpGroup.deletePet
                        .call(
                      petID: id,
                    )
                        .then((value) {
                      // Navigator.pop(context, value);
                      context.pop(value);
                      context.pop(value);

                      if (value == false) {
                        showSnackbar(
                          context,
                          FFLocalizations.of(context).getVariableText(
                            ptText: 'Erro ao excluir pet',
                            enText: 'Error deleting pet',
                          ),
                          true,
                        );
                      } else if (value == true) {
                        showSnackbar(
                          context,
                          FFLocalizations.of(context).getVariableText(
                            enText: 'Success deleting pet',
                            ptText: 'Succeso ao excluir pet',
                          ),
                          false,
                        );
                      }
                    }).catchError((err, stack) {
                      context.pop();
                      showSnackbar(
                        context,
                        FFLocalizations.of(context).getVariableText(
                          enText: 'Error deleting pet',
                          ptText: 'Erro ao excluir pet',
                        ),
                        true,
                      );
                    });
                  });
                },
                options: FFButtonOptions(
                  height: 40,
                  color: FlutterFlowTheme.of(context).primaryBackground,
                  elevation: 0,
                  textStyle: TextStyle(
                    color: FlutterFlowTheme.of(context).primaryText,
                    fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15),
                  ),
                  splashColor: const Color.fromARGB(131, 255, 17, 0),
                  borderSide: BorderSide(
                    color: FlutterFlowTheme.of(context).primaryBackground,
                    width: 1,
                  ),
                  // borderRadius: 12,
                ),
              ),
            ]
          : [],
      labelsHashMap: Map<String, String>.from({
        if (item['species'] != null && item['species'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:':
              item['species'].toString().toUpperCase(),
        if (item['breed'] != null && item['breed'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:':
              item['breed'].toString().toUpperCase(),
        if (item['color'] != null && item['color'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:':
              item['color'].toString().toUpperCase(),
        if (item['birthdayDate'] != null && item['birthdayDate'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Data de Nascimento", enText: "Date of Birth")}:':
              ValidatorUtil.formatDateTimePicker(item['birthdayDate']),
        if (item['gender'] != null && item['gender'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Gênero", enText: "Gender")}:':
              item['gender'] == 'MAC'
                  ? FFLocalizations.of(context)
                      .getVariableText(ptText: 'MACHO', enText: 'MALE')
                  : FFLocalizations.of(context)
                      .getVariableText(enText: 'FEMALE', ptText: 'FÊMEA'),
        if (item['size'] != null && item['size'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Porte", enText: "Size")}:':
              item['size'] == 'MIN'
                  ? FFLocalizations.of(context)
                      .getVariableText(ptText: 'MINI', enText: 'MINI')
                  : item['size'] == 'PEQ'
                      ? FFLocalizations.of(context)
                          .getVariableText(ptText: 'PEQUENO', enText: 'SMALL')
                      : item['size'] == 'MED'
                          ? FFLocalizations.of(context).getVariableText(
                              ptText: 'MÉDIO', enText: 'MEDIUM')
                          : item['size'] == 'GRD'
                              ? FFLocalizations.of(context).getVariableText(
                                  ptText: 'GRANDE', enText: 'LARGE')
                              : item['size'] == 'GIG'
                                  ? FFLocalizations.of(context).getVariableText(
                                      ptText: 'GIGANTE', enText: 'GIANT')
                                  : '',
        if (item['notes'] != null && item['notes'] != '')
          '${FFLocalizations.of(context).getVariableText(ptText: "Observação", enText: "Notes")}:':
              item['notes'] ?? '',
      }),
      imagePath:
          'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=${item['id'] ?? ''}',
      statusHashMap: [
        if (item['gender'] == "MAC")
          Map<String, Color>.from({
            item['name']: const Color(0xFF094CB0),
          }),
        if (item['gender'] == "FEM")
          Map<String, Color>.from({
            item['name']: const Color(0xFFE463E7),
          }),
      ],
    );
  }
}
