import 'dart:async';
import 'dart:convert';
import 'dart:js' as js;

import 'package:guru_fb_game/model/model.dart';

class FbGameGlobalUtils {
  static Future<dynamic> getFBProfile() {
    final completer = Completer<dynamic>();

    js.context.callMethod('getFBProfileWithUid', [
      (success) => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> shareGame(FbShareData data) {
    final completer = Completer<dynamic>();

    js.context.callMethod('shareGame', [
      json.encode(data.toJson()),
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> inviteUser(FbInviteData data) {
    final completer = Completer<dynamic>();

    js.context.callMethod('inviteUser', [
      json.encode(data.toJson()),
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Map<String, dynamic> getEntryPointData() {
    final result = js.context.callMethod('getEntryPointData');
    return json.decode(result);
  }

  static String getLocale() {
    final result = js.context.callMethod('getLocale');
    return result ?? "";
  }

  static String getPlatform() {
    String result = "web";
    result = js.context.callMethod('getPlatform');
    return result;
  }
}

class FbGamePlayerUtils {
  static void saveData(Map<String, dynamic> data) {
    js.context.callMethod('fbSetData', [json.encode(data)]);
  }

  static Future<dynamic> getData(List<String> keys) {
    final completer = Completer<dynamic>();

    js.context.callMethod('fbGetData', [
      json.encode(keys),
      (success) => completer.complete(json.decode(success)),
      (error) => completer.completeError(json.decode(error)),
    ]);

    return completer.future;
  }

  //获取当前环境下的用户信息，包括用户id，用户名称，用户头像
  Future<dynamic> getPlayersAsync() async {
    final completer = Completer<dynamic>();
    js.context.callMethod('getPlayersAsync', [
      (value) {
        List<Map<String, dynamic>> players = json.decode(value);
        final users = players.map((e) => FbUserInfo.fromJson(e)).toList();
        completer.complete(users);
      },
      (error) => completer.completeError(json.decode(error)),
    ]);
    return completer.future;
  }

  /**
   * 获取玩家同玩好友的信息
   * 返回的值是数组
   */
  Future<dynamic> getConnectedPlayersAsync() {
    final completer = Completer<dynamic>();
    js.context.callMethod('getConnectedPlayersAsync', [
      (value) {
        List<Map<String, dynamic>> players = json.decode(value);
        final users = players.map((e) => FbUserInfo.fromJson(e)).toList();
        completer.complete(users);
      },
      (error) => completer.completeError(json.decode(error)),
    ]);
    return completer.future;
  }

  static Future<dynamic> subscribeBot() {
    final completer = Completer<dynamic>();

    js.context.callMethod('subscribeBot', [
      () => completer.complete(),
      (error) => completer.completeError(json.decode(error)),
    ]);

    return completer.future;
  }
}

class FbGameTournamentUtils {
  static Future<dynamic> createTournament(num initialScore, FbTournamentConfig config, Map<String, String> data) {
    final completer = Completer<dynamic>();

    js.context.callMethod('createTournament', [
      initialScore,
      json.encode(config.toJson()),
      json.encode(data),
      (value) => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> postTournamentScore(String id, num score) {
    final completer = Completer<dynamic>();

    js.context.callMethod('postTournamentScore', [
      id,
      score,
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> shareTournament(num score, Map<String, dynamic> data) {
    final completer = Completer<dynamic>();

    js.context.callMethod('shareTournament', [
      score,
      json.encode(data),
      (value) => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> getCurrentTournament() {
    final completer = Completer<dynamic>();

    js.context.callMethod('getCurrentTournament', [
      (success) => completer.complete(json.decode(success)),
      (error) => completer.completeError(error),
    ]);

    // success 返回 map
    // {
    //         id: tournament.getContextID(),
    //         endTime: tournament.getEndTime(),
    //         title: tournament.getTitle(),
    //         payLoad: tournament.getPayload()
    //       }

    return completer.future;
  }
}

class FbGameContextUtils {
  static Future<dynamic> createAsync(String playerId) {
    final completer = Completer<dynamic>();
    js.context.callMethod('createAsync', [
      playerId,
      (value) => completer.complete(),
      (error) => completer.completeError(json.decode(error)),
    ]);
    return completer.future;
  }

  static void updateAsync(String img) {
    js.context.callMethod('updateAsync', [img]);
  }

  static FBContextInfo getContext() {
    final result = js.context.callMethod('getContextInfo');
    return FBContextInfo.fromJson(json.decode(result));
  }

  static Future<dynamic> contextSwitchAsync(String contextId) {
    final completer = Completer<dynamic>();
    js.context.callMethod('contextSwitchAsync', [
      contextId,
      () => completer.complete(),
      (error) => completer.completeError(json.decode(error)),
    ]);
    return completer.future;
  }

  //切换当前环境，如果选择朋友，则可以获取到朋友的信息
  static Future<dynamic> chooseContext() async {
    final completer = Completer<dynamic>();
    js.context.callMethod('chooseContext', [
      (value) => completer.complete(FBContextInfo.fromJson(json.decode(value))),
      (error) => completer.completeError(json.decode(error)),
    ]);
    return completer.future;
  }
}

class FbGameLogUtils {
  static void fbLogEvent(String eventName, int valueToSum, Map<String, dynamic> params) {
    js.context.callMethod('logEvent', [eventName, valueToSum, json.encode(params)]);
  }

  static void initGuruLogEvent(InitGuruLogEventData data) {
    js.context.callMethod('initEventLogger', [json.encode(data.toJson())]);
  }

  static void guruLogEvent(String eventName, Map<String, dynamic> params, Map<String, dynamic> properties) {
    js.context.callMethod('castboxLogEvent', [eventName, json.encode(params), json.encode(properties)]);
  }
}

class FbGameAdUtils {
  static List<String> checkSupportedAds() {
    final String listStr = js.context.callMethod("checkSupportedAds");
    List<String> list = json.decode(listStr);
    return list;
  }

  static Future<dynamic> showBanner(String id) {
    final completer = Completer<dynamic>();

    js.context.callMethod('showBannerAds', [
      id,
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> hideBanner(String id) {
    final completer = Completer<dynamic>();

    js.context.callMethod('hideBannerAds', [
      id,
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> loadInterstitial(String id) {
    final completer = Completer<dynamic>();

    js.context.callMethod('loadInterstitial', [
      id,
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> showInterstitial() {
    final completer = Completer<dynamic>();

    js.context.callMethod('showInterstitial', [
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> loadRewarded(String id) {
    final completer = Completer<dynamic>();

    js.context.callMethod('loadRewarded', [
      id,
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }

  static Future<dynamic> showRewarded() {
    final completer = Completer<dynamic>();

    js.context.callMethod('showRewarded', [
      () => completer.complete(),
      (error) => completer.completeError(error),
    ]);

    return completer.future;
  }
}