import 'dart:convert';
import 'package:design/design.dart';
import 'package:guru_app/analytics/guru_analytics.dart';
import 'package:guru_app/financial/iap/iap_manager.dart';
import 'package:guru_app/financial/product/product_model.dart';
import 'package:guru_app/guru_app.dart';
import 'package:guru_ui/pages/store/store_page.dart';
import 'package:guru_app/controller/assets_aware.dart';
import 'package:guru_popup/guru_popup.dart';
import 'package:guru_widgets/assetbar/guru_asset_bar.dart';
import 'package:guru_widgets/dialog/guru_dialog.dart';
import 'package:guru_widgets/overlay/guru_asset_controller.dart';
import 'package:guru_ui/localizations/ui_strings.dart';
import 'package:guru_widgets/theme/guru_theme.dart';

class StoreController extends GuruAssetOverlayController with AssetsAware {
  final Map<String, GlobalKey> keys = <String, GlobalKey>{};
  bool productsInitFinished = false;

  final assetBarStyle = GuruTheme.of(Get.context!).assetBarTheme.styles[GuruAssetBarStyle.igc];

  GlobalKey getKey(String key) {
    return keys[key] ??= GlobalKey();
  }

  void handlePurchase(ProductId productId) async {
    Log.w("handlePurchase");
    final products =
        await IapManager.instance.buildProducts({productId.createIntent(scene: "store")});
    final product = products.getProduct(productId);
    final appStrings = UIStrings.get();
    // final store = currentProductStore;
    // final product = store.getProduct(productId);

    if (product != null) {
      GuruAnalytics.instance
          .logEventEx("iap_gems_clk", itemCategory: "store", itemName: productId.sku);

      final successStream =
          Stream<bool>.fromFuture(requestProduct(product).catchError((error, stacktrace) {
        Log.w("requestProduct error! $error", stackTrace: stacktrace);
        return false;
      })).asBroadcastStream();

      Log.d(
          "request product:${product.sku} ${jsonEncode(product.manifest)} ${product.manifest.details.length}");

      final completer = GuruPopup.instance
          .showFeedbackLoading(successStream: successStream, feedbackText: 'Purchase Succeeded');

      successStream.listen((event) async {
        Log.v("buy result:$event");
        if (event) {
          GuruAnalytics.instance
              .logEventEx("iap_gem_scs", itemCategory: "home", itemName: product.sku);
          await Future.delayed(const Duration(milliseconds: 1000));
          completer.complete();
          GuruPopup.instance.showStandardDialog(
              illustration: Image.asset('assets/images/ic_purchase.png', package: 'guru_ui'),
              closable: false,
              title: 'Completed',
              summary: 'Your purchase is complete. Have fun playing th game!',
              primaryButtonAction: 'Continue',
              onPrimaryButtonPressed: () {
                final assetsCompleter = GuruPopup.instance.showAssetsOverlay(director);
                startClaim(50,
                  scene: 'asset_overlay',
                  assetIcon: assetBarStyle!.assetIcon,
                  key: getKey("assetBar"),
                  onCompleted: () {
                  assetsCompleter.complete();
                });
                return DialogResult(true, null);
              });
        } else {
          completer.complete();
          if (isIapCanceled) {
            GuruPopup.instance.showStandardOverlay("Purchase Failed", icon: "assets/images/ic_purchase_failed.png", package: 'guru_ui');
          } else {
            GuruPopup.instance.showStandardOverlay("Purchase Failed", icon: "assets/images/ic_purchase_failed.png", package: 'guru_ui');
          }
        }
      });
    }
  }

  Set<TransactionIntent> initIntents(List<ProductItem> list) {
    final List<ProductId> ids = [];
    for (var item in list) {
      if (item is InseparableProductItem) {
        ids.add(item.productId);
      }
      if (item is ComposableProductItem) {
        for (var childItem in item.items) {
          ids.add(childItem.productId);
        }
      }
    }
    final Set<ProductId> idsSet = Set.of(ids.toSet());
    final intents = idsSet.map((id) => id.createIntent(scene: "store")).toSet();
    return intents;
  }

  void initProducts(List<ProductItem> list) {
    if (!productsInitFinished) {
      final intents = initIntents(list);
      observeIapProducts(intents);
      productsInitFinished = true;
    }
  }
}
