import 'dart:convert';

import 'package:dio/dio.dart' as Dio;
import 'package:get/get.dart';
import 'package:sk_base_mobile/apis/index.dart';
import 'package:sk_base_mobile/util/logger_util.dart';
import 'package:sk_base_mobile/widgets/tap_to_dismiss_keyboard.dart';
import 'package:sk_base_mobile/models/auth.dart';
import 'package:sk_base_mobile/models/user_info.model.dart';
import 'package:sk_base_mobile/services/service.dart';
import '../constants/constants.dart';
import '../util/util.dart';

class AuthStore extends GetxController {
  static AuthStore get to => Get.find();
  final userInfo = UserInfoModel().obs;

  Future<AuthStore> init() async {
    try {
      String? preUserInfo =
          StorageService.to.getString(CacheKeys.userInfo, isWithUser: false);
      String? token =
          StorageService.to.getString(CacheKeys.token, isWithUser: false);

      if (token != null) {
        if (preUserInfo != null) {
          userInfo(UserInfoModel.fromJson(jsonDecode(preUserInfo)));
          LoggerUtil().info('[Store-Auth] userId: ${userInfo.value.id}');
        }
      }
    } catch (e) {
      LoggerUtil().info(
        '[Store-Auth]Init failed, please try again.${e}',
      );
    }
    return this;
  }

  Future<void> deleteAccount() async {
    await LoadingUtil.to.show(status: 'Deleting...');
    try {
      final response = await Api.deleteAccount();
      if (response.data != null) {
        await SnackBarUtil().success('Delete account succeed.');
        await logout();
      }
    } catch (e) {
      await SnackBarUtil().error('Delete account faield. Please try again.');
    } finally {
      await LoadingUtil.to.dismiss();
      ;
    }
  }

  Future<void> logout({bool force = false}) async {
    await StorageService.to.remove(CacheKeys.token, isWithUser: false);
    await StorageService.to.remove(CacheKeys.userInfo, isWithUser: false);
    try {
      // final response = await Api.logout();
      // if (response.data != null) {
      LoggerUtil().info('[Store-Auth] Logout succeed.');
      Get.offAllNamed(RouteConfig.login);
      // }
    } catch (e) {
      print(e);
    } finally {
      LoadingUtil.to.dismiss();
    }
  }

  Future<void> login(
      {required String username, required String password}) async {
    Dio.Response response;
    // if (type == LoginEnum.fastLogin &&
    //     StorageService.to.getString(CacheKeys.deviceUUID, isWithUser: false) ==
    //         null) {
    //   SnackBarUtil().error('Need DeviceUUID. Please restart app.');
    //   return;
    // }

    LoadingUtil.to.show();
    TapToDismissKeyboard.dismissOf(context: Get.context!);
    try {
      await Future.delayed(const Duration(seconds: 1));
      response = await Api.login(username, password);
      if (response.data != null) {
        final auth = Auth.fromJson(response.data['data']);

        if (auth.token != null) {
          await StorageService.to
              .setString(CacheKeys.token, auth.token!, isWithUser: false);
        }
        await getUserInfo();
        Get.offNamed(RouteConfig.home);
        // getCommonInfo();
      }
    } catch (e) {
      await SnackBarUtil().error('账号密码错误');
      LoggerUtil().error(e);
    } finally {
      LoadingUtil.to.dismiss();
    }
  }

  Future<void> updateUserInfoState(UserInfoModel newInfo) async {
    userInfo(newInfo);
    await StorageService.to
        .setString(CacheKeys.userInfo, jsonEncode(newInfo), isWithUser: false);
  }

  Future<void> getUserInfo() async {
    await LoadingUtil.to.show();
    try {
      final response = await Api.getUserInfo();
      if (response.data != null) {
        UserInfoModel userInfo = UserInfoModel.fromJson(response.data);
        await updateUserInfoState(userInfo);
      }
    } catch (e) {
      SnackBarUtil().error('$e');
    } finally {
      LoadingUtil.to.dismiss();
    }
  }

  Future<void> saveUserInfo(Map<String, dynamic> data) async {
    LoadingUtil.to.show(status: 'Saving...');
    try {
      final res = await Api.saveUserInfo(data);
      if (res.data != null) {
        await getUserInfo();
        SnackBarUtil().success('Save successfully.');
      }
    } catch (e) {
      SnackBarUtil().error('$e');
    } finally {
      LoadingUtil.to.dismiss();
    }
  }

  Future<void> getCommonInfo() async {
    await AppInfoService.to.getAppConfig();
    await Future.wait([
      /// 依赖业务信息
      // Get.putAsync<BlockStore>(() => BlockStore().init()),
    ]);
  }
}
