// Copyright 2013 The Flutter 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:io';

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
import 'package:in_app_purchase_storekit/src/channel.dart';
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';

import '../store_kit_wrappers/sk_test_stub_objects.dart';

class FakeStoreKitPlatform {
  FakeStoreKitPlatform() {
    _ambiguate(TestDefaultBinaryMessengerBinding.instance)!
        .defaultBinaryMessenger
        .setMockMethodCallHandler(channel, onMethodCall);
  }

  // pre-configured store information
  String? receiptData;
  late Set<String> validProductIDs;
  late Map<String, SKProductWrapper> validProducts;
  late List<SKPaymentTransactionWrapper> transactions;
  late List<SKPaymentTransactionWrapper> finishedTransactions;
  late bool testRestoredTransactionsNull;
  late bool testTransactionFail;
  late int testTransactionCancel;
  PlatformException? queryProductException;
  PlatformException? restoreException;
  SKError? testRestoredError;
  bool queueIsActive = false;
  Map<String, dynamic> discountReceived = <String, dynamic>{};

  void reset() {
    transactions = <SKPaymentTransactionWrapper>[];
    receiptData = 'dummy base64data';
    validProductIDs = <String>{'123', '456'};
    validProducts = <String, SKProductWrapper>{};
    for (final String validID in validProductIDs) {
      final Map<String, dynamic> productWrapperMap =
          buildProductMap(dummyProductWrapper);
      productWrapperMap['productIdentifier'] = validID;
      if (validID == '456') {
        productWrapperMap['priceLocale'] = buildLocaleMap(noSymbolLocale);
      }
      validProducts[validID] = SKProductWrapper.fromJson(productWrapperMap);
    }

    finishedTransactions = <SKPaymentTransactionWrapper>[];
    testRestoredTransactionsNull = false;
    testTransactionFail = false;
    testTransactionCancel = -1;
    queryProductException = null;
    restoreException = null;
    testRestoredError = null;
    queueIsActive = false;
    discountReceived = <String, dynamic>{};
  }

  SKPaymentTransactionWrapper createPendingTransaction(String id,
      {int quantity = 1}) {
    return SKPaymentTransactionWrapper(
      transactionIdentifier: '',
      payment: SKPaymentWrapper(productIdentifier: id, quantity: quantity),
      transactionState: SKPaymentTransactionStateWrapper.purchasing,
      transactionTimeStamp: 123123.121,
    );
  }

  SKPaymentTransactionWrapper createPurchasedTransaction(
      String productId, String transactionId,
      {int quantity = 1}) {
    return SKPaymentTransactionWrapper(
        payment:
            SKPaymentWrapper(productIdentifier: productId, quantity: quantity),
        transactionState: SKPaymentTransactionStateWrapper.purchased,
        transactionTimeStamp: 123123.121,
        transactionIdentifier: transactionId);
  }

  SKPaymentTransactionWrapper createFailedTransaction(String productId,
      {int quantity = 1}) {
    return SKPaymentTransactionWrapper(
        transactionIdentifier: '',
        payment:
            SKPaymentWrapper(productIdentifier: productId, quantity: quantity),
        transactionState: SKPaymentTransactionStateWrapper.failed,
        transactionTimeStamp: 123123.121,
        error: const SKError(
            code: 0,
            domain: 'ios_domain',
            userInfo: <String, Object>{'message': 'an error message'}));
  }

  SKPaymentTransactionWrapper createCanceledTransaction(
      String productId, int errorCode,
      {int quantity = 1}) {
    return SKPaymentTransactionWrapper(
        transactionIdentifier: '',
        payment:
            SKPaymentWrapper(productIdentifier: productId, quantity: quantity),
        transactionState: SKPaymentTransactionStateWrapper.failed,
        transactionTimeStamp: 123123.121,
        error: SKError(
            code: errorCode,
            domain: 'ios_domain',
            userInfo: const <String, Object>{'message': 'an error message'}));
  }

  SKPaymentTransactionWrapper createRestoredTransaction(
      String productId, String transactionId,
      {int quantity = 1}) {
    return SKPaymentTransactionWrapper(
        payment:
            SKPaymentWrapper(productIdentifier: productId, quantity: quantity),
        transactionState: SKPaymentTransactionStateWrapper.restored,
        transactionTimeStamp: 123123.121,
        transactionIdentifier: transactionId);
  }

  Future<dynamic> onMethodCall(MethodCall call) {
    switch (call.method) {
      case '-[SKPaymentQueue canMakePayments:]':
        return Future<bool>.value(true);
      case '-[InAppPurchasePlugin startProductRequest:result:]':
        if (queryProductException != null) {
          throw queryProductException!;
        }
        final List<String> productIDS =
            List.castFrom<dynamic, String>(call.arguments as List<dynamic>);
        final List<String> invalidFound = <String>[];
        final List<SKProductWrapper> products = <SKProductWrapper>[];
        for (final String productID in productIDS) {
          if (!validProductIDs.contains(productID)) {
            invalidFound.add(productID);
          } else {
            products.add(validProducts[productID]!);
          }
        }
        final SkProductResponseWrapper response = SkProductResponseWrapper(
            products: products, invalidProductIdentifiers: invalidFound);
        return Future<Map<String, dynamic>>.value(
            buildProductResponseMap(response));
      case '-[InAppPurchasePlugin restoreTransactions:result:]':
        if (restoreException != null) {
          throw restoreException!;
        }
        if (testRestoredError != null) {
          InAppPurchaseStoreKitPlatform.observer
              .restoreCompletedTransactionsFailed(error: testRestoredError!);
          return Future<void>.sync(() {});
        }
        if (!testRestoredTransactionsNull) {
          InAppPurchaseStoreKitPlatform.observer
              .updatedTransactions(transactions: transactions);
        }
        InAppPurchaseStoreKitPlatform.observer
            .paymentQueueRestoreCompletedTransactionsFinished();

        return Future<void>.sync(() {});
      case '-[InAppPurchasePlugin retrieveReceiptData:result:]':
        if (receiptData != null) {
          return Future<String>.value(receiptData);
        } else {
          throw PlatformException(code: 'no_receipt_data');
        }
      case '-[InAppPurchasePlugin refreshReceipt:result:]':
        receiptData = 'refreshed receipt data';
        return Future<void>.sync(() {});
      case '-[InAppPurchasePlugin addPayment:result:]':
        final Map<String, Object?> arguments = _getArgumentDictionary(call);
        final String id = arguments['productIdentifier']! as String;
        final int quantity = arguments['quantity']! as int;

        // Keep the received paymentDiscount parameter when testing payment with discount.
        if (arguments['applicationUsername']! == 'userWithDiscount') {
          final Map<dynamic, dynamic>? discountArgument =
              arguments['paymentDiscount'] as Map<dynamic, dynamic>?;
          if (discountArgument != null) {
            discountReceived = discountArgument.cast<String, dynamic>();
          } else {
            discountReceived = <String, dynamic>{};
          }
        }

        final SKPaymentTransactionWrapper transaction =
            createPendingTransaction(id, quantity: quantity);
        transactions.add(transaction);
        InAppPurchaseStoreKitPlatform.observer.updatedTransactions(
            transactions: <SKPaymentTransactionWrapper>[transaction]);
        sleep(const Duration(milliseconds: 30));
        if (testTransactionFail) {
          final SKPaymentTransactionWrapper transactionFailed =
              createFailedTransaction(id, quantity: quantity);
          InAppPurchaseStoreKitPlatform.observer.updatedTransactions(
              transactions: <SKPaymentTransactionWrapper>[transactionFailed]);
        } else if (testTransactionCancel > 0) {
          final SKPaymentTransactionWrapper transactionCanceled =
              createCanceledTransaction(id, testTransactionCancel,
                  quantity: quantity);
          InAppPurchaseStoreKitPlatform.observer.updatedTransactions(
              transactions: <SKPaymentTransactionWrapper>[transactionCanceled]);
        } else {
          final SKPaymentTransactionWrapper transactionFinished =
              createPurchasedTransaction(
                  id, transaction.transactionIdentifier ?? '',
                  quantity: quantity);
          InAppPurchaseStoreKitPlatform.observer.updatedTransactions(
              transactions: <SKPaymentTransactionWrapper>[transactionFinished]);
        }
        break;
      case '-[InAppPurchasePlugin finishTransaction:result:]':
        final Map<String, Object?> arguments = _getArgumentDictionary(call);
        finishedTransactions.add(createPurchasedTransaction(
            arguments['productIdentifier']! as String,
            arguments['transactionIdentifier']! as String,
            quantity: transactions.first.payment.quantity));
        break;
      case '-[SKPaymentQueue startObservingTransactionQueue]':
        queueIsActive = true;
        break;
      case '-[SKPaymentQueue stopObservingTransactionQueue]':
        queueIsActive = false;
        break;
    }
    return Future<void>.sync(() {});
  }

  /// Returns the arguments of [call] as typed string-keyed Map.
  ///
  /// This does not do any type validation, so is only safe to call if the
  /// arguments are known to be a map.
  Map<String, Object?> _getArgumentDictionary(MethodCall call) {
    return (call.arguments as Map<Object?, Object?>).cast<String, Object?>();
  }
}

/// This allows a value of type T or T? to be treated as a value of type T?.
///
/// We use this so that APIs that have become non-nullable can still be used
/// with `!` and `?` on the stable branch.
T? _ambiguate<T>(T? value) => value;
