import 'package:flutter/material.dart';
import 'package:hub/features/backend/index.dart';
import 'package:hub/features/local/index.dart';
import 'package:hub/features/storage/index.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/utils/device_util.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:hub/shared/utils/snackbar_util.dart';

import '../../../flutter_flow/flutter_flow_util.dart';
import '../../../flutter_flow/random_data_util.dart';

class AuthenticationService {
  static Future<void> login(BuildContext context) async {
    try {
      final GetLocalsCall callback = PhpGroup.getLocalsCall;
      final response = await callback.call();

      if (response.jsonBody['error']) {
        await DialogUtil.errorDefault(context);
        return;
      }

      List<dynamic> locals = response.jsonBody['locais'] ?? [];

      if (locals.isEmpty) {
        await StorageHelper().set(SecureStorageKey.haveLocal.value, false);
        context.go('/receptionPage');
      } else {
        await StorageHelper().set(SecureStorageKey.isLogged.value, true);
        context
            .go('/homePage', extra: {'update': LocalsRepositoryImpl().update});
      }
    } catch (e, s) {
      await DialogUtil.errorDefault(context);
      LogUtil.requestAPIFailed('getLocals.php', '', "Get Locals", e, s);
    }
  }

  static Future signIn(
    BuildContext context,
    FlutterFlowModel model, {
    String? emailAdress,
    String? password,
  }) async {
    try {
      final ApiCallResponse? response;
      final LoginCall callback = PhpGroup.loginCall;
      String deviceDescription = randomString(10, 10, true, false, false);
      await StorageHelper()
          .set(SecureStorageKey.deviceDescription.value, deviceDescription);

      final String? devUUID;
      final String userUUID;
      final String status;
      final String userDevUUID;
      final String userName;
      final String email;
      final String passwd;

      email = emailAdress!;
      passwd = password!;
      devUUID = await DeviceUtil.getDevUUID();

      if ((email != '') && (passwd != '')) {
        await StorageHelper().set(SecureStorageKey.email.value, email);
        await StorageHelper().set(SecureStorageKey.password.value, passwd);
        await StorageHelper().set(ProfileStorageKey.devUUID.key, devUUID!);
        response = await callback.call();

        if (response.jsonBody['error'] == false) {
          userUUID = response.jsonBody['uid'];
          status = response.jsonBody['user']['status'];
          userDevUUID = response.jsonBody['user']['dev_id'];
          userName = response.jsonBody['user']['name'];

          await StorageHelper().set(ProfileStorageKey.userUUID.key, userUUID);
          await StorageHelper()
              .set(ProfileStorageKey.userDevUUID.key, userDevUUID);
          await StorageHelper().set(ProfileStorageKey.status.key, status);
          await StorageHelper().set(ProfileStorageKey.userName.key, userName);

          await login(context);
        } else {
          if (response.jsonBody['error'] == null) {
            await DialogUtil.errorDefault(context);
          } else {
            await DialogUtil.error(
                context, response.jsonBody['error_msg'].toString());
          }
        }
      }
      return;
    } catch (e, s) {
      await DialogUtil.errorDefault(context);
      LogUtil.requestAPIFailed(
          'login.php', emailAdress.toString(), "Login", e, s);
    }
  }

  static Future<bool> signUp(
    BuildContext context, {
    required String? name,
    String? passwd,
    required String? email,
    String? device,
  }) async {
    try {
      ApiCallResponse? response;
      if ((email != null && email != '') &&
          (passwd != null && passwd != '' && passwd.length > 7) &&
          (name != null && name != '')) {
        response = await PhpGroup.registerCall.call(
          name: name,
          password: passwd,
          email: email,
          token: randomString(36, 36, false, false, true),
          uuid: randomString(36, 36, false, false, true),
          tipo: device!,
          descricao: randomString(36, 36, true, false, false),
        );

        if (response.jsonBody['error'] == false) return true;
        await DialogUtil.error(context, response.jsonBody['error_msg']);
        return false;
      } else {
        await DialogUtil.errorDefault(context);
        return false;
      }
    } catch (e, s) {
      await DialogUtil.errorDefault(context);
      LogUtil.requestAPIFailed(
          'registro.php', email.toString(), "Register", e, s);
      return false;
    }
  }

  static Future<void> signOut(BuildContext context) async {
    await PhpGroup.unregisterDevice.call();
    final Map<String, dynamic> extra = <String, dynamic>{
      kTransitionInfoKey: const TransitionInfo(
        hasTransition: true,
        transitionType: PageTransitionType.scale,
        alignment: Alignment.bottomCenter,
      ),
    };

    await StorageHelper().clean(Storage.databaseStorage);
    await StorageHelper().clean(Storage.secureStorage);

    DatabaseService.isInitialized = false;
    await DatabaseService.instance.init();

    context.go('/welcomePage', extra: extra);
  }

  static Future<bool> forgotPassword(BuildContext context, String email) async {
    try {
      final ApiCallResponse? response;
      final ForgotPasswordCall callback = PhpGroup.forgotPasswordCall;
      final String message = FFLocalizations.of(context).getVariableText(
          enText: "Send E-mail Successful!",
          ptText: "E-mail Enviado com Sucesso!");

      response = await callback.call(email: email);

      if (response.jsonBody['error'] == false) {
        await DialogUtil.success(context, message);
        return true;
      } else {
        await DialogUtil.error(context, response.jsonBody['error_msg']);
        return false;
      }
    } catch (e, s) {
      await DialogUtil.errorDefault(context);
      LogUtil.requestAPIFailed(
          'forgotPassword.php', email, "Forgot Password", e, s);
      return false;
    }
  }

  static Future<bool> changePassword(
      BuildContext context, String email, String password, String token) async {
    try {
      final ApiCallResponse response = await PhpGroup.changePasswordCall
          .call(email: email, psswd: password, token: token);

      if (response.jsonBody['error'] == false) {
        final String message = FFLocalizations.of(context).getVariableText(
          enText: "Password changed successfully!",
          ptText: "Senha alterada com sucesso!",
        );
        await DialogUtil.success(context, message).then((_) => context.pop);
        return true;
      } else {
        final String message = response.jsonBody['error_msg'];
        await DialogUtil.error(context, message);
        return false;
      }
    } catch (e, s) {
      await DialogUtil.errorDefault(context);
      LogUtil.requestAPIFailed(
          'changePassword.php', email, "Change Password", e, s);
      return false;
    }
  }

  static Future<void> deleteAccount(BuildContext context) async {
    String content;
    try {
      await PhpGroup.deleteAccount.call().then((value) async {
        if (value.jsonBody['error'] == false) {
          content = FFLocalizations.of(context).getVariableText(
            enText: 'Account deleted successfully',
            ptText: 'Conta deletada com sucesso',
          );
          return await signOut(context);
        }
      }).catchError((err) {
        context.pop();
        content = FFLocalizations.of(context).getVariableText(
          enText: 'Error deleting account',
          ptText: 'Erro ao deletar conta',
        );
        SnackBarUtil.showSnackBar(context, content);
        return;
      });
    } catch (err) {
      context.pop();
      content = FFLocalizations.of(context).getVariableText(
        enText: 'Error deleting account',
        ptText: 'Erro ao deletar conta',
      );
      SnackBarUtil.showSnackBar(context, content, isError: true);
      return;
    }
  }
}
