import 'dart:io';

import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:flutter/services.dart';
import 'package:purchases_flutter/purchases_flutter.dart';
import 'package:aitrainer_app/model/product.dart' as wtproduct;

class RevenueCatPurchases with Logging {
  static final RevenueCatPurchases _singleton = RevenueCatPurchases._internal();
  Offering? _offering;
  String? appUserId;

  factory RevenueCatPurchases() {
    return _singleton;
  }

  RevenueCatPurchases._internal();

  Offering? get offering => _offering;

  Future<void> initPlatform() async {
    if (Cache().userLoggedIn != null) {
      await Purchases.setDebugLogsEnabled(true);
      await Purchases.setup("yLxGFWaeRtThLImqznvBnUEKjgArSsZE", appUserId: Cache().userLoggedIn!.customerId.toString());
      appUserId = await Purchases.appUserID;
      log("AppUserId: $appUserId");
      await Purchases.setAllowSharingStoreAccount(true);
      await this.restore();
    }
  }

  Future<void> restore() async {
    if (appUserId != null) {
      try {
        //PurchaserInfo purchaserInfo = await Purchases.restoreTransactions();
        PurchaserInfo purchaserInfo = await Purchases.getPurchaserInfo();
        if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
          Cache().hasPurchased = true;
          log(" ******************************************** ");
          log(" Purchase active ! ");
        } else {
          log(" ** No subscription active");
        }
      } on PlatformException catch (e) {
        log("Purchaserinfo not reachable " + e.toString());
      }
    }
    bool inTrial = Cache().userLoggedIn!.trialDate != null && DateTime.now().difference(Cache().userLoggedIn!.trialDate!).inDays < 10;
    log("Trial mode: $inTrial  date: ${Cache().userLoggedIn!.trialDate}");
    if (Cache().userLoggedIn!.admin == 1 || inTrial || Cache().userLoggedIn!.lifeLong == 1) {
      Cache().hasPurchased = true;
      log(" -- Purchased -- ");
    }
  }

  Future<Offering?> getOfferings() async {
    if (appUserId == null) {
      await initPlatform();
    }
    log(" .. acessing offerings...");
    try {
      Offerings offerings = await Purchases.getOfferings();
      if (offerings.current != null && offerings.current!.availablePackages.isNotEmpty) {
        // Display packages for sale
        _offering = offerings.current;
      } else {
        log("No current offerings");
      }
    } on PlatformException catch (e) {
      // optional error handling
      log("!!!! Getting offerings error " + e.toString());
    }
    return _offering;
  }

  Future<void> makePurchase(wtproduct.Product product) async {
    if (_offering == null) {
      _offering = await getOfferings();
    }
    if (_offering != null) {
      String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!;
      Package? selectedPackage;
      log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId);
      for (var package in _offering!.availablePackages) {
        log("package to check " + package.product.identifier.toString());
        if (package.product.identifier == productId) {
          selectedPackage = package;
          log("**** Selected package to purchase" + package.product.identifier);
          break;
        }
      }
      if (selectedPackage != null) {
        PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage);
        if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
          Cache().hasPurchased = true;
          log(" -- Purchased -- ");
        }
      } else {
        log("!!!! No Selected package to purchase");
        throw Exception("No Selected package to purchase");
      }
    } else {
      log("!!!! No active offering");
      throw Exception("No active offering");
    }
  }
}