import 'dart:async';
import 'dart:io';
import 'dart:math' as math;

import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/product.dart';
import 'package:aitrainer_app/model/product_test.dart';
import 'package:aitrainer_app/model/purchase.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/service/purchase_service.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/purchases.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flurry/flurry.dart';
import 'package:purchases_flutter/offering_wrapper.dart';

part 'sales_event.dart';
part 'sales_state.dart';

class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
  List<ProductTest> tests = List();
  List<Product> product2Display = List();
  int productSet = -1;
  SalesBloc() : super(SalesInitial());

  @override
  Stream<SalesState> mapEventToState(
    SalesEvent event,
  ) async* {
    try {
      if (event is SalesLoad) {
        yield SalesLoading();
        log("Load Sales");
        Track().track(TrackingEvent.sales_page);
        //await PlatformPurchaseApi().initPurchasePlatform();
        await RevenueCatPurchases().getOfferings();
        this.getProductSet();
        yield SalesReady();
      } else if (event is SalesPurchase) {
        if (Cache().hasPurchased) {
          throw Exception("You have already a successfull subscription");
        }
        yield SalesLoading();
        final int productId = event.productId;
        log("Requesting purchase for: " + productId.toString());
        Track().track(TrackingEvent.purchase_request);
        final Product selectedProduct = this.getSelectedProduct(productId);
        log("SelectedProduct for purchase " + selectedProduct.toString());
        await RevenueCatPurchases().makePurchase(selectedProduct);
        if (Cache().hasPurchased) {
          Purchase purchase = Purchase(customerId: Cache().userLoggedIn.customerId, productId: productId);
          purchase.dateAdd = DateTime.now();
          purchase.purchaseSum = 0;
          purchase.currency = "EUR";
          await PurchaseApi().savePurchase(purchase);
          Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
          Common.sendMessage("Purchase: " + purchase.toJson().toString());
        }
        yield SalesSuccessful();
      }
    } on Exception catch (ex) {
      yield SalesError(message: ex.toString());
    }
  }

  Product getSelectedProduct(int productId) {
    Product prod;
    for (var product in this.product2Display) {
      if (product.productId == productId) {
        prod = product;
      }
    }
    return prod;
  }

  String getLocalizedPrice(String productId) {
    String price = "";
    Offering offering = RevenueCatPurchases().offering;
    if (offering != null) {
      for (var package in offering.availablePackages) {
        log("PlatformProduct " + package.toString());
        if (productId == package.product.identifier) {
          price = package.product.priceString;
          if (price.contains(r'HUF')) {
            price = price.replaceAll(RegExp(r'HUF'), 'Ft');
            price = price.replaceAll(RegExp(r',00'), "");
          }
          break;
        }
      }
    } else {
      log(" !!! No Offering");
    }
    return price;
  }

  void getProductSet() {
    int productId = 0;
    this.tests = Cache().productTests;

    if (tests.isEmpty) {
      var rand = math.Random.secure();
      productSet = rand.nextInt(5) + 1;
    } else {
      trace("Previous ProductTest: " + tests[0].toJson().toString());
      productId = tests[0].productId;
      for (var elem in Cache().products) {
        final Product product = elem as Product;
        if (product.productId == productId) {
          productSet = product.productSet;
          break;
        }
      }
    }

    ProductTest productTest = ProductTest();

    productSet = 2;
    log("ProductSet: " + productSet.toString());
    for (var elem in Cache().products) {
      Product product = elem as Product;

      if (product.productSet == productSet) {
        productId = product.productId;
        final String platformProductId = Platform.isAndroid ? product.productIdAndroid : product.productIdIos;
        product.localizedPrice = getLocalizedPrice(platformProductId);
        product2Display.add(product);
      }
    }

    product2Display.sort((a, b) {
      return a.sort < b.sort ? a.sort : b.sort;
    });

    productTest.productId = productId;
    productTest.customerId = Cache().userLoggedIn.customerId;
    productTest.dateView = DateTime.now();
    //ProductTestApi().saveProductTest(productTest);
    //Cache().productTests.add(productTest);
  }
}