import 'dart:async';

import 'package:flutter/material.dart';
import 'package:hub/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart';
import 'package:hub/features/auth/index.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/flutter_flow_util.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/shared/utils/path_util.dart';
import 'package:share_plus/share_plus.dart';

import '../../shared/utils/snackbar_util.dart';

class PreferencesPageModel with ChangeNotifier {
  final unfocusNode = FocusNode();

  late bool isFingerprint = false;
  late bool isPerson = false;
  late bool isNotify = false;
  late bool isAccess = false;
  late bool isPanic = false;

  Future<void> _initialize() async {
    await LocalsRepositoryImpl().fetch(navigatorKey.currentContext!);
    isFingerprint =
        await StorageHelper().get(LocalsStorageKey.fingerprint.key) == 'true';
    isPerson = await StorageHelper().get(LocalsStorageKey.person.key) == 'true';
    isNotify = await StorageHelper().get(LocalsStorageKey.notify.key) == 'true';
    isAccess = await StorageHelper().get(LocalsStorageKey.access.key) == 'true';
    isPanic = await StorageHelper().get(LocalsStorageKey.panic.key) == 'true';
    notifyListeners();
  }

  PreferencesPageModel() {
    _initialize();
  }

  Future<void> enablePerson(BuildContext context) async {
    final String userDevUUID =
        (await StorageHelper().get(ProfileStorageKey.userDevUUID.key)) ?? '';
    notifyListeners();
    Share.share(
      FFLocalizations.of(context).getVariableText(
        ptText: 'Este é o meu identificador de acesso: $userDevUUID',
        enText: 'This is my access identifier: $userDevUUID',
      ),
    );
  }

  Future<void> toggleNotify(BuildContext context) async {
    final String title = FFLocalizations.of(context).getVariableText(
      enText: 'Change notification',
      ptText: 'Alterar notificação',
    );
    final String content = FFLocalizations.of(context).getVariableText(
      enText: 'Are you sure you want to change your notification?',
      ptText: 'Tem certeza que deseja alterar sua notificação?',
    );

    onConfirm() async {
      String content;
      String value = !isNotify ? 'S' : 'N';
      await PhpGroup.changeNotifica
          .call(notifica: value)
          .then((value) async {
            if (value.jsonBody['error'] == false) {
              await StorageHelper().set(LocalsStorageKey.notify.key, !isNotify);
              content = FFLocalizations.of(context).getVariableText(
                enText: 'Setting changed successfully',
                ptText: 'Opção alterada com sucesso',
              );
              notifyListeners();
              SnackBarUtil.showSnackBar(context, content);
            } else {
              content = FFLocalizations.of(context).getVariableText(
                enText: 'Error changing notification',
                ptText: 'Erro ao alterar notificação',
              );
              SnackBarUtil.showSnackBar(context, content, isError: true);
            }
          })
          .catchError((e, s) {
            content = FFLocalizations.of(context).getVariableText(
              enText: 'Error changing notification',
              ptText: 'Erro ao alterar notificação',
            );
            SnackBarUtil.showSnackBar(context, content, isError: true);
          })
          .then((_) async => isNotify =
              await StorageHelper().get(LocalsStorageKey.notify.key) == 'true')
          .whenComplete(() => notifyListeners());
      context.pop();
    }

    showAlertDialog(context, title, content, onConfirm);
  }

  Future<void> toggleIdentification(BuildContext context) async {
    final String title = FFLocalizations.of(context).getVariableText(
      ptText: 'Atualizar Identificador de Acesso',
      enText: 'Update Access Identifier',
    );

    final String content = FFLocalizations.of(context).getVariableText(
      ptText: 'Tem certeza que deseja habilitar seu dispositivo para acesso?',
      enText: 'Are you sure you want to enable your device for access?',
    );
    onConfirm() async {
      String content;
      await PhpGroup.updateIDE.call().then((value) async {
        if (value.jsonBody['error'] == false) {
          notifyListeners();
          content = FFLocalizations.of(context).getVariableText(
            ptText:
                'Atualização  do identificador de acesso realizada com sucesso',
            enText: 'Access identifier updated successfully',
          );
          SnackBarUtil.showSnackBar(context, content);
        } else {
          content = FFLocalizations.of(context).getVariableText(
            ptText: 'Erro ao atualizar identificador de acesso',
            enText: 'Error updating access identifier',
          );
          SnackBarUtil.showSnackBar(context, content, isError: true);
        }
      }).catchError((e, s) {
        content = FFLocalizations.of(context).getVariableText(
          ptText: 'Erro ao atualizar identificador de acesso',
          enText: 'Error updating access identifier',
        );
        SnackBarUtil.showSnackBar(context, content, isError: true);
      }).whenComplete(() => notifyListeners());
      context.pop();
    }

    showAlertDialog(context, title, content, onConfirm);
  }

  Future<void> toggleAccess(BuildContext context) async {
    onChange(String key) async {
      await StorageHelper().set(SecureStorageKey.accessPass.value, key);
      await PhpGroup.changePass
          .call(newSenha: key)
          .then((value) async {
            final String content;
            if (jsonDecode(value.jsonBody['error'].toString()) == false) {
              await StorageHelper()
                  .set(LocalsStorageKey.access.key, isAccess ? false : true);
              notifyListeners();
              content = FFLocalizations.of(context).getVariableText(
                enText: 'Access pass changed successfully',
                ptText: 'Senha de acesso alterada com sucesso',
              );
              SnackBarUtil.showSnackBar(context, content);
            } else {
              content = FFLocalizations.of(context).getVariableText(
                ptText: 'Erro ao alterar senha de acesso',
                enText: 'Error changing access pass',
              );
              SnackBarUtil.showSnackBar(context, content, isError: true);
            }
          })
          .catchError((e, s) {
            final String content = FFLocalizations.of(context).getVariableText(
              ptText: 'Erro ao alterar senha de acesso',
              enText: 'Error changing access pass',
            );
            SnackBarUtil.showSnackBar(context, content, isError: true);
          })
          .then((_) async => isAccess =
              await StorageHelper().get(LocalsStorageKey.access.key) == 'true')
          .whenComplete(() => notifyListeners());
    }

    _showPassKey(context, onChange);
  }

  Future<void> togglePanic(BuildContext context) async {
    onChange(String key) async {
      await StorageHelper().set(SecureStorageKey.panicPass.value, key);
      await PhpGroup.changePanic
          .call(newSenhaPanico: key)
          .then((value) async {
            final String content;
            if (jsonDecode(value.jsonBody['error'].toString()) == false) {
              await StorageHelper()
                  .set(LocalsStorageKey.panic.key, isPanic ? 'false' : 'true');
              notifyListeners();
              content = FFLocalizations.of(context).getVariableText(
                enText: 'Panic password changed successfully',
                ptText: 'Senha de pânico alterada com sucesso',
              );
              SnackBarUtil.showSnackBar(context, content);
            } else {
              content = FFLocalizations.of(context).getVariableText(
                ptText: 'Erro ao alterar senha de pânico',
                enText: 'Error changing panic password',
              );
              SnackBarUtil.showSnackBar(context, content, isError: true);
            }
          })
          .catchError((e, s) {
            final String content = FFLocalizations.of(context).getVariableText(
              ptText: 'Erro ao alterar senha de pânico',
              enText: 'Error changing panic password',
            );
            SnackBarUtil.showSnackBar(context, content, isError: true);
          })
          .then((_) async => isPanic =
              await StorageHelper().get(LocalsStorageKey.panic.key) == 'true')
          .whenComplete(() => notifyListeners());
    }

    _showPassKey(context, onChange);
  }

  Future<void> toggleFingerprint(BuildContext context) async {
    final String content = FFLocalizations.of(context).getVariableText(
      enText: 'Fingerprint changed successfully',
      ptText: 'Impressão digital alterada com sucesso',
    );

    onChange(String? key) async {
      isFingerprint = !isFingerprint;
      await StorageHelper()
          .set(SecureStorageKey.fingerprintPass.value, key ?? '');
      await StorageHelper().set(
          LocalsStorageKey.fingerprint.key, isFingerprint ? 'true' : 'false');
      notifyListeners();
      SnackBarUtil.showSnackBar(context, content);
      isFingerprint =
          await StorageHelper().get(LocalsStorageKey.fingerprint.key) == 'true';
    }

    isFingerprint ? onChange(null) : _showPassKey(context, onChange);
  }

  Future<void> deleteAccount(BuildContext context) async {
    final String title = FFLocalizations.of(context).getVariableText(
      enText: 'Delete account',
      ptText: 'Deletar conta',
    );
    final String content = FFLocalizations.of(context).getVariableText(
      enText: 'Are you sure you want to delete your account?',
      ptText: 'Tem certeza que deseja deletar sua conta?',
    );
    onConfirm() async => AuthenticationService.deleteAccount(context);

    showAlertDialog(context, title, content, onConfirm);
  }

  void navAboutSystem(BuildContext context) async {
    PathUtil.nav('/aboutSystemPage');
  }

  void localUnlink(BuildContext context) {
    final String title = FFLocalizations.of(context).getVariableText(
      enText: 'Unlink device',
      ptText: 'Desvincular dispositivo',
    );
    final String content = FFLocalizations.of(context).getVariableText(
      enText: 'Are you sure you want to unlink your device?',
      ptText: 'Tem certeza que deseja desvincular seu dispositivo?',
    );
    onConfirm() async => LocalsRepositoryImpl().unlinkLocal(context);

    showAlertDialog(context, title, content, onConfirm);
  }

  void _showPassKey(
      BuildContext context, void Function(String) onChange) async {
    await showModalBottomSheet(
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      useSafeArea: true,
      context: context,
      builder: (context) {
        return Padding(
          padding: MediaQuery.viewInsetsOf(context),
          child: PassKeyTemplateWidget(
            toggleActionStatus: (key) async {
              onChange.call(key);
            },
          ),
        );
      },
    ).catchError((err, stack) {
      final String content = FFLocalizations.of(context).getVariableText(
        enText: 'Error changing key',
        ptText: 'Erro ao alterar senha',
      );
      SnackBarUtil.showSnackBar(context, content, isError: true);
    }).whenComplete(() => notifyListeners());
  }
}
