import 'package:get/get.dart';
import 'package:injectable/injectable.dart';
import 'package:keyboard/base/app_base_request.dart';
import 'package:keyboard/data/api/request/keyboard_character_update_request.dart';
import 'package:keyboard/data/api/request/keyboard_generate_request.dart';
import 'package:keyboard/data/api/request/keyboard_list_request.dart';
import 'package:keyboard/data/api/response/keyboard_generate_response.dart';
import 'package:keyboard/data/api/response/keyboard_love_index_response.dart';
import 'package:keyboard/data/api/response/keyboard_meme_explain_response.dart';
import 'package:keyboard/data/api/response/keyboard_prologue_list_response.dart';
import 'package:keyboard/utils/atmob_log.dart';
import 'dart:convert';
import '../../di/get_it.dart';
import '../../module/keyboard_manage/keyboard_manage_controller.dart';
import '../../utils/async_util.dart';
import '../../utils/http_handler.dart';
import '../api/atmob_api.dart';
import '../api/request/keyboard_character_list_request.dart';
import '../api/request/keyboard_character_start_request.dart';
import '../api/request/keyboard_choose_request.dart';
import '../api/request/keyboard_meme_explain_request.dart';
import '../api/request/keyboard_update_request.dart';
import '../api/response/keyboard_character_list_response.dart';
import '../api/response/keyboard_home_info_response.dart';
import '../api/response/keyboard_list_response.dart';
import '../bean/keyboard_info.dart';
import '../consts/error_code.dart';

@lazySingleton
class KeyboardRepository {
  final tag = "KeyboardRepository";
  final AtmobApi atmobApi;

  final RxList<KeyboardInfo> _keyboardInfoList = RxList();

  RxList<KeyboardInfo> get keyboardInfoList => _keyboardInfoList;

  final RxList<KeyboardInfo> _customKeyboardInfoList = RxList();

  RxList<KeyboardInfo> get customKeyboardInfoList => _customKeyboardInfoList;

  final Rxn<KeyboardLoveIndexResponse> _homeLoveIndex =
      Rxn<KeyboardLoveIndexResponse>();

  Rxn<KeyboardLoveIndexResponse> get homeLoveIndex => _homeLoveIndex;

  final Rxn<KeyboardHomeInfoResponse> _homeInfo =
      Rxn<KeyboardHomeInfoResponse>();

  Rxn<KeyboardHomeInfoResponse> get homeInfo => _homeInfo;

  CancelableFuture? homeInfoFuture;
  CancelableFuture? homeLoveIndexFuture;

  final Rxn<KeyboardInfo> _chooseKeyboardInfo = Rxn<KeyboardInfo>(null);

  Rxn<KeyboardInfo> get chooseKeyboardInfo => _chooseKeyboardInfo;

  KeyboardRepository(this.atmobApi) {
    print('$tag....init');
    refreshData();
  }

  Future refreshData() async {
    _homeLoveIndex.value = null;
    await Future.delayed(const Duration(milliseconds: 500));
    // 延迟为了保证首页数据能够正常获取，不然保存的时候，获取太快了，导致还是拉到旧的数值
    refreshUserInfo();
    await Future.delayed(const Duration(milliseconds: 300));
    getKeyboardHomeInfo();
    // 注销登录后，重新获取键盘列表。过快拉取服务端会直接返回空数据，导致人设页数据没有通用键盘
    await Future.delayed(const Duration(milliseconds: 300));
    refreshKeyboardList();
    refreshLoveIndex();
  }

  void refreshUserInfo() async {
    homeInfoFuture?.cancel();
    homeInfoFuture = AsyncUtil.retryWithExponentialBackoff(
      () => getKeyboardHomeInfo(),
      10,
      predicate: (error) {
        if (error is ServerErrorException) {
          return error.code != ErrorCode.noLoginError;
        }
        return true;
      },
    );
  }

  void refreshLoveIndex() {
    homeLoveIndexFuture?.cancel();
    homeLoveIndexFuture = AsyncUtil.retryWithExponentialBackoff(
      () => getKeyboardLoveIndex(),
      10,
      predicate: (error) {
        if (error is ServerErrorException) {
          return error.code != ErrorCode.noLoginError;
        }
        return true;
      },
    );
  }


  Future refreshKeyboardList() async {
    return getKeyboardList().then((response) {
      _keyboardInfoList.value = response.keyboardInfos;
      final chosen = response.keyboardInfos.firstWhereOrNull(
        (e) => e.isChoose == true,
      );
      if (chosen != null) {
        _chooseKeyboardInfo.value = chosen;
      }
      // 过滤掉系统键盘
      _customKeyboardInfoList.value =
          response.keyboardInfos
              .where((keyboard) => keyboard.type != KeyboardType.system.name)
              .toList();
    });
  }

  // 获取键盘列表
  Future<KeyboardListResponse> getKeyboardList({String? type}) {
    return atmobApi
        .getKeyboardList(KeyboardListRequest(type: type))
        .then(HttpHandler.handle(true));
  }

  // 获取键盘人设列表
  Future<KeyboardCharacterListResponse> getKeyboardCharacterList({
    required String keyboardId,
  }) {
    return atmobApi
        .getKeyboardCharacterList(
          KeyboardCharacterListRequest(keyboardId: keyboardId),
        )
        .then(HttpHandler.handle(true));
  }

  //更新键盘人设
  Future<void> keyboardCharacterUpdate({
    required List<String> characterIds,
    required String keyboardId,
  }) {
    return atmobApi
        .keyboardCharacterUpdate(
          KeyboardCharacterUpdateRequest(
            keyboardId: keyboardId,
            characterIds: characterIds,
          ),
        )
        .then(HttpHandler.handle(true));
  }

  Future<void> keyboardCharacterStart({
    required List<String> characterIds,
    required String keyboardId,
  }) {
    return atmobApi
        .keyboardCharacterStart(
          KeyboardCharacterStartRequest(
            keyboardId: keyboardId,
            characterIds: characterIds,
          ),
        )
        .then(HttpHandler.handle(true));
  }

  // 更新键盘信息
  Future<void> updateKeyboardInfo({
    required String keyboardId,
    String? name,
    String? imageUrl,
    String? birthday,
    int? intimacy,
    int? gender,
  }) {
    return atmobApi
        .keyboardUpdate(
          KeyboardUpdateRequest(
            keyboardId: keyboardId,
            name: name,
            imageUrl: imageUrl,
            birthday: birthday,
            intimacy: intimacy,
            gender: gender,
          ),
        )
        .then(HttpHandler.handle(true));
  }

  // 选择键盘
  Future<void> keyboardChoose({required String keyboardId}) {
    return atmobApi
        .keyboardChoose(KeyboardChooseRequest(keyboardId: keyboardId))
        .then(HttpHandler.handle(true));
  }

  // 获取开场白列表
  Future<KeyboardPrologueListResponse> getPrologueList() {
    return atmobApi
        .getPrologueList(AppBaseRequest())
        .then(HttpHandler.handle(true));
  }

  // 获取首页信息
  Future<KeyboardHomeInfoResponse> getKeyboardHomeInfo() {
    return atmobApi
        .getKeyboardHomeInfo(AppBaseRequest())
        .then(HttpHandler.handle(true))
        .then((response) {
          _homeInfo.value = response;
          return response;
        });
  }

  // 获取恋爱指数
  Future<KeyboardLoveIndexResponse> getKeyboardLoveIndex() {
    return atmobApi
        .getKeyboardLoveIndex(AppBaseRequest())
        .then(HttpHandler.handle(false))
        .then((response) {
          _homeLoveIndex.value = response;
          return response;
        });
  }

  // 生成键盘
  Future<KeyboardGenerateResponse> getKeyboardGenerate({
    required String name,
    required String imageUrl,
    required String birthday,
    required int intimacy,
    required int gender,
  }) {
    return atmobApi
        .keyboardGenerate(
          KeyboardGenerateRequest(
            intimacy: intimacy,
            name: name,
            gender: gender,
            birthday: birthday,
            imageUrl: imageUrl,
          ),
        )
        .then(HttpHandler.handle(true))
        .then((response) {
          return response;
        });
  }

  Future<KeyboardMemeExplainResponse> getKeyboardMemeExplain({
    required String birthday,
    required String targetBirthday,
  }) {
    return atmobApi
        .getKeyboardMemeExplain(
          KeyboardMemeExplainRequest(
            birthday: birthday,
            targetBirthday: targetBirthday,
          ),
        )
        .then(HttpHandler.handle(true));
  }

  static KeyboardRepository getInstance() => getIt.get<KeyboardRepository>();
}
