// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:in_app_purchase/src/in_app_purchase/purchase_details.dart';
import 'in_app_purchase_connection.dart';
import 'product_details.dart';
import 'package:in_app_purchase/store_kit_wrappers.dart';
import 'package:in_app_purchase/src/store_kit_wrappers/enum_converters.dart';
import '../../billing_client_wrappers.dart';

/// An [InAppPurchaseConnection] that wraps StoreKit.
///
/// This translates various `StoreKit` calls and responses into the
/// generic plugin API.
class AppStoreConnection implements InAppPurchaseConnection {
  /// Returns the singleton instance of the [AppStoreConnection] that should be
  /// used across the app.
  static AppStoreConnection get instance => _getOrCreateInstance();
  static AppStoreConnection? _instance;
  static late SKPaymentQueueWrapper _skPaymentQueueWrapper;
  static late _TransactionObserver _observer;

  /// Creates an [AppStoreConnection] object.
  ///
  /// This constructor should only be used for testing, for any other purpose
  /// get the connection from the [instance] getter.
  @visibleForTesting
  AppStoreConnection();

  Stream<List<PurchaseDetails>> get purchaseUpdatedStream =>
      _observer.purchaseUpdatedController.stream;

  /// Callback handler for transaction status changes.
  @visibleForTesting
  static SKTransactionObserverWrapper get observer => _observer;

  static AppStoreConnection _getOrCreateInstance() {
    if (_instance != null) {
      return _instance!;
    }

    _instance = AppStoreConnection();
    _skPaymentQueueWrapper = SKPaymentQueueWrapper();
    _observer = _TransactionObserver(StreamController.broadcast());
    _skPaymentQueueWrapper.setTransactionObserver(observer);
    return _instance!;
  }

  @override
  Future<bool> isAvailable() => SKPaymentQueueWrapper.canMakePayments();

  @override
  Future<bool> buyNonConsumable({required PurchaseParam purchaseParam}) async {
    await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper(
        productIdentifier: purchaseParam.productDetails.id,
        quantity: 1,
        applicationUsername: purchaseParam.applicationUserName,
        simulatesAskToBuyInSandbox: purchaseParam.simulatesAskToBuyInSandbox ||
            // ignore: deprecated_member_use_from_same_package
            purchaseParam.sandboxTesting,
        requestData: null));
    return true; // There's no error feedback from iOS here to return.
  }

  @override
  Future<bool> buyConsumable(
      {required PurchaseParam purchaseParam, bool autoConsume = true}) {
    assert(autoConsume == true, 'On iOS, we should always auto consume');
    return buyNonConsumable(purchaseParam: purchaseParam);
  }

  @override
  Future<BillingResultWrapper> completePurchase(PurchaseDetails purchase,
      {String? developerPayload}) async {
    if (purchase.skPaymentTransaction == null) {
      throw ArgumentError(
          'completePurchase unsuccessful. The `purchase.skPaymentTransaction` is not valid');
    }
    await _skPaymentQueueWrapper
        .finishTransaction(purchase.skPaymentTransaction!);
    return BillingResultWrapper(responseCode: BillingResponse.ok);
  }

  @override
  Future<BillingResultWrapper> consumePurchase(PurchaseDetails purchase,
      {String? developerPayload}) {
    throw UnsupportedError('consume purchase is not available on Android');
  }

  @override
  Future<QueryPurchaseDetailsResponse> queryPastPurchases(
      {String? applicationUserName}) async {
    IAPError? error;
    List<PurchaseDetails> pastPurchases = [];

    try {
      String receiptData = await _observer.getReceiptData();
      final List<SKPaymentTransactionWrapper> restoredTransactions =
          await _observer.getRestoredTransactions(
              queue: _skPaymentQueueWrapper,
              applicationUserName: applicationUserName);
      pastPurchases =
          restoredTransactions.map((SKPaymentTransactionWrapper transaction) {
        assert(transaction.transactionState ==
            SKPaymentTransactionStateWrapper.restored);
        return PurchaseDetails.fromSKTransaction(transaction, receiptData)
          ..status = SKTransactionStatusConverter()
              .toPurchaseStatus(transaction.transactionState)
          ..error = transaction.error != null
              ? IAPError(
                  source: IAPSource.AppStore,
                  code: kPurchaseErrorCode,
                  message: transaction.error?.domain ?? '',
                  details: transaction.error?.userInfo,
                )
              : null;
      }).toList();
      _observer.cleanUpRestoredTransactions();
    } on PlatformException catch (e) {
      error = IAPError(
          source: IAPSource.AppStore,
          code: e.code,
          message: e.message ?? '',
          details: e.details);
    } on SKError catch (e) {
      error = IAPError(
          source: IAPSource.AppStore,
          code: kRestoredPurchaseErrorCode,
          message: e.domain,
          details: e.userInfo);
    }
    return QueryPurchaseDetailsResponse(
        pastPurchases: pastPurchases, error: error);
  }

  @override
  Future<PurchaseVerificationData?> refreshPurchaseVerificationData() async {
    await SKRequestMaker().startRefreshReceiptRequest();
    final String? receipt = await SKReceiptManager.retrieveReceiptData();
    if (receipt == null) {
      return null;
    }
    return PurchaseVerificationData(
        localVerificationData: receipt,
        serverVerificationData: receipt,
        source: IAPSource.AppStore);
  }

  /// Query the product detail list.
  ///
  /// This method only returns [ProductDetailsResponse].
  /// To get detailed Store Kit product list, use [SkProductResponseWrapper.startProductRequest]
  /// to get the [SKProductResponseWrapper].
  @override
  Future<ProductDetailsResponse> queryProductDetails(
      Set<String> identifiers) async {
    final SKRequestMaker requestMaker = SKRequestMaker();
    SkProductResponseWrapper response;
    PlatformException? exception;
    try {
      response = await requestMaker.startProductRequest(identifiers.toList());
    } on PlatformException catch (e) {
      exception = e;
      response = SkProductResponseWrapper(
          products: [], invalidProductIdentifiers: identifiers.toList());
    }
    List<ProductDetails> productDetails = [];
    if (response.products != null) {
      productDetails = response.products
          .map((SKProductWrapper productWrapper) =>
              ProductDetails.fromSKProduct(productWrapper))
          .toList();
    }
    List<String> invalidIdentifiers = response.invalidProductIdentifiers;
    if (productDetails.isEmpty) {
      invalidIdentifiers = identifiers.toList();
    }
    ProductDetailsResponse productDetailsResponse = ProductDetailsResponse(
      productDetails: productDetails,
      notFoundIDs: invalidIdentifiers,
      error: exception == null
          ? null
          : IAPError(
              source: IAPSource.AppStore,
              code: exception.code,
              message: exception.message ?? '',
              details: exception.details),
    );
    return productDetailsResponse;
  }
}

class _TransactionObserver implements SKTransactionObserverWrapper {
  final StreamController<List<PurchaseDetails>> purchaseUpdatedController;

  Completer<List<SKPaymentTransactionWrapper>>? _restoreCompleter;
  List<SKPaymentTransactionWrapper> _restoredTransactions =
      <SKPaymentTransactionWrapper>[];
  late String _receiptData;

  _TransactionObserver(this.purchaseUpdatedController);

  Future<List<SKPaymentTransactionWrapper>> getRestoredTransactions(
      {required SKPaymentQueueWrapper queue, String? applicationUserName}) {
    _restoreCompleter = Completer();
    queue.restoreTransactions(applicationUserName: applicationUserName);
    return _restoreCompleter!.future;
  }

  void cleanUpRestoredTransactions() {
    _restoredTransactions.clear();
    _restoreCompleter = null;
  }

  void updatedTransactions(
      {required List<SKPaymentTransactionWrapper> transactions}) async {
    if (_restoreCompleter != null) {
      if (_restoredTransactions == null) {
        _restoredTransactions = [];
      }
      _restoredTransactions
          .addAll(transactions.where((SKPaymentTransactionWrapper wrapper) {
        return wrapper.transactionState ==
            SKPaymentTransactionStateWrapper.restored;
      }).map((SKPaymentTransactionWrapper wrapper) => wrapper));
    }

    String receiptData = await getReceiptData();
    purchaseUpdatedController
        .add(transactions.where((SKPaymentTransactionWrapper wrapper) {
      return wrapper.transactionState !=
          SKPaymentTransactionStateWrapper.restored;
    }).map((SKPaymentTransactionWrapper transaction) {
      PurchaseDetails purchaseDetails =
          PurchaseDetails.fromSKTransaction(transaction, receiptData);
      return purchaseDetails;
    }).toList());
  }

  void removedTransactions(
      {required List<SKPaymentTransactionWrapper> transactions}) {}

  /// Triggered when there is an error while restoring transactions.
  void restoreCompletedTransactionsFailed({required SKError error}) {
    _restoreCompleter!.completeError(error);
  }

  void paymentQueueRestoreCompletedTransactionsFinished() {
    _restoreCompleter!.complete(_restoredTransactions);
  }

  bool shouldAddStorePayment(
      {required SKPaymentWrapper payment, required SKProductWrapper product}) {
    // In this unified API, we always return true to keep it consistent with the behavior on Google Play.
    return true;
  }

  Future<String> getReceiptData() async {
    try {
      _receiptData = await SKReceiptManager.retrieveReceiptData();
    } catch (e) {
      _receiptData = '';
    }
    return _receiptData;
  }
}
