import 'dart:convert';
import 'dart:io';

import 'package:guru_app/analytics/guru_analytics.dart';
import 'package:guru_app/firebase/remoteconfig/remote_config_manager.dart';
import 'package:guru_app/guru_app.dart';
import 'package:guru_app/property/app_property.dart';
import 'package:guru_app/property/property_keys.dart';
import 'package:guru_utils/collection/collectionutils.dart';
import 'package:guru_utils/datetime/datetime_utils.dart';
import 'package:guru_utils/log/log.dart';
import 'package:guru_applovin_flutter/ad_impression.dart';

import 'ads_config.dart';
import 'exceptions/ads_exceptions.dart';

const ltvPhaseNames = [
  "tch_ad_rev_top40",
  "tch_ad_rev_top30",
  "tch_ad_rev_top20",
  "tch_ad_rev_top10",
  "tch_ad_rev_top5"
];

class AdImpressionController {
  final List<double> ltvThresholds = <double>[];
  final Map<String, String> adsParams = <String, String>{};
  static String latestImpressionPayload = "";
  TaichiConfig? taichiConfig;

  AdImpressionController() {}

  Future _init() async {
    try {
      taichiConfig = RemoteConfigManager.instance.getTaichiConfig();
      final config = taichiConfig;
      if (config != null && config.enable && config.threshold.isNotEmpty) {
        Log.d("set thresholds prepare! ${config.threshold}");
        final thresholdStrings = config.threshold.split(",");
        if (thresholdStrings.isNotEmpty) {
          try {
            final thresholds = thresholdStrings.map((e) => double.parse(e)).toList();
            ltvThresholds.clear();
            ltvThresholds.addAll(thresholds);
            Log.d("set thresholds success! $thresholds");
          } catch (error, stacktrace) {
            Log.d("set thresholds error!", error: error, stackTrace: stacktrace);
          }
        }
      }
    } catch (error, stacktrace) {
      Log.d('AdImpressionController params TaichiConfig err', error: error, stackTrace: stacktrace);
    }
  }

  void init() async {
    await _init();

    AdImpressionListener.addCallback((event, Map<dynamic, dynamic> arguments) async {
      Log.d("------------addListener arguments$arguments");
      switch (event) {
        case AdImpressionEvent.onAdImpression:
          if (arguments != null) {
            final payload = arguments["payload"];
            if (payload == null || payload.isEmpty) {
              break;
            }
            final payloadMap = json.decode(payload);
            ImpressionData impressionData = ImpressionData.fromJson(payloadMap);
            await refreshLtv(impressionData);

            final jsonPayload = jsonEncode(impressionData.payload);
            latestImpressionPayload = jsonPayload;
            if (impressionData.publisherRevenue > 0) {
              // AdjustAdRevenue adRevenue = AdjustAdRevenue(AdjustConfig.AdRevenueSourceAppLovinMAX);
              // adRevenue.setRevenue(impressionData.publisherRevenue, "USD");
              // adRevenue.adRevenueNetwork = impressionData.networkName;
              // adRevenue.adRevenueUnit = impressionData.unitId;
              // adRevenue.adRevenuePlacement = impressionData.networkPlacementId;
              // Adjust.trackAdRevenueNew(adRevenue);

              GuruAnalytics.instance.loadAdjustAdRevenue(impressionData);
            }
          }
          break;
      }
    });
  }

  _reportAdImpression(Map<dynamic, dynamic> arguments) {
    // adFormat 为:BANNER,REWARDED,INTER
    final adFormat = arguments["ad_format"] ?? "";
    GuruAnalytics.instance.logAdImpression("max_imp", adFormat,
        adName: Platform.isIOS ? "isd_$adFormat" : "sd_$adFormat");
  }

  void onImpression(Map<dynamic, dynamic> arguments) {}

  Future refreshLtv(ImpressionData impressionData) async {
    final revenue = impressionData.publisherRevenue;
    final adPlatform = impressionData.platform;
    final currency = impressionData.currency;
    if (revenue != -1) {
      _logAdRevenue(impressionData);
      // if ()
      // _logAdLtv(revenue: revenue, adPlatform: adPlatform, currency: currency);
    }
    Log.d("refreshLtv payload:${impressionData.payload}");
  }

  // Future _logAdLtv({double revenue = 0.0, String adPlatform = "MAX", String currency = ""}) async {
  //   final nowDate = DateTimeUtils.yyyyMMddUtcNum;
  //   final appProperty = AppProperty.getInstance();
  //   final totalLtv = await appProperty.getDouble(PropertyKeys.totalLtv, defValue: 0.0);
  //   final previousDate = await appProperty.getInt(PropertyKeys.previousLtvDate, defValue: 0);
  //   double previousLtv = await appProperty.getDouble(PropertyKeys.previousLtv, defValue: 0.0);
  //   if (previousDate != nowDate) {
  //     previousLtv = 0.0;
  //     appProperty.setInt(PropertyKeys.previousLtvDate, nowDate);
  //   }
  //   final currentLtv = previousLtv + revenue;
  //   for (int i = 0; i < ltvThresholds.length; ++i) {
  //     if (previousLtv < ltvThresholds[i] && currentLtv >= ltvThresholds[i]) {
  //       if (i < ltvPhaseNames.length) {
  //         Analytics.instance.logAdLtv(ltvPhaseNames[i], currentLtv);
  //       }
  //     }
  //   }
  //   AppProperty.getInstance().setDouble(PropertyKeys.previousLtv, currentLtv);
  //   AppProperty.getInstance().setDouble(PropertyKeys.totalLtv, totalLtv + revenue);
  // }

  _logAdRevenue(ImpressionData data) async {
    final appProperty = AppProperty.getInstance();

    GuruAnalytics.instance.logAdImp(data);

    final abnormalThreshold = taichiConfig?.abnormalThreshold ?? 1;
    if (data.publisherRevenue >= abnormalThreshold) {
      try {
        final parameters = CollectionUtils.filterOutNulls(<String, dynamic>{
          "ad_platform": data.platform,
          "value": data.publisherRevenue,
          "currency": data.currency,
          "ad_format": data.unitFormat,
          "ad_source": data.networkName,
          "ad_unit_name": data.unitName,
          "country": data.country,
          "precision": data.precision
        });
        GuruAnalytics.instance.logEvent("tch_ad_rev_value_abnormal", parameters);
        final payload = data.payload;
        GuruAnalytics.instance.logException(AbnormalRevenueException(payload.toString()),
            stacktrace: StackTrace.current);
        Log.d(payload.toString());
        return;
      } catch (error, stacktrace) {
        Log.d("convert impression data error! $error", stackTrace: stacktrace);
      }
    }

    double totalRevenue = await appProperty.getDouble(PropertyKeys.totalRevenue, defValue: 0.0);
    totalRevenue += data.publisherRevenue;
    if (totalRevenue >= 0.01) {
      GuruAnalytics.instance.logAdRevenue(totalRevenue, data.platform, data.currency);
      if (GuruApp.instance.appSpec.deployment.purchaseEventTrigger == 1) {
        GuruAnalytics.instance.logPurchase(totalRevenue,
            currency: data.currency, contentId: "MAX", adPlatform: "MAX");
      }
      totalRevenue = .0;
    }
    appProperty.setDouble(PropertyKeys.totalRevenue, totalRevenue);

    double totalRevenue020 =
        await appProperty.getDouble(PropertyKeys.totalRevenue020, defValue: 0.0);
    totalRevenue020 += data.publisherRevenue;
    if (totalRevenue020 >= 0.2) {
      GuruAnalytics.instance.logAdRevenue020(totalRevenue020, data.platform, data.currency);
      if (GuruApp.instance.appSpec.deployment.purchaseEventTrigger == 2) {
        GuruAnalytics.instance.logPurchase(totalRevenue020,
            currency: data.currency, contentId: "MAX", adPlatform: "MAX");
      }
      totalRevenue020 = .0;
    }
    appProperty.setDouble(PropertyKeys.totalRevenue020, totalRevenue020);
  }
}
