//
//  TCGBPurchase.h
//  Gamebase
//
//  Created by NHN on 2016. 6. 8..
//  © NHN Corp. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <Gamebase/TCGBError.h>
#import <Gamebase/TCGBConstants.h>
#import <Gamebase/TCGBPurchasePendingDelegate.h>
#import <Gamebase/TCGBPurchaseVerifyItem.h>
#import <Gamebase/TCGBPurchasableConfiguration.h>

NS_ASSUME_NONNULL_BEGIN

@class TCGBLaunching;
@class TCGBPurchasableItem;
@class TCGBPurchasableReceipt;
@class TCGBPurchasableRetryTransactionResult;

/** The TCGBPurchase class provides several APIs related to purchasing processes.<br/>
 * Before using these APIs, You should be logged in. Because every TCGBPurchase API need informations that are obtained from TCGBServer.<br/>
 * If you do not have been authenticated, you will get **TCGB_ERROR_NOT_LOGGED_IN** error.
 */
@interface TCGBPurchase : NSObject

+ (void)initializePurchaseWithLaunching:(TCGBLaunching *)launching completion:(void(^)(TCGBError *error))completion;

/**---------------------------------------------------------------------------------------
 * @name Request Item List
 *  ---------------------------------------------------------------------------------------
 */

/** This is the primary method for obtaining ItemList which is registered at NHN Cloud IAP Console and Apple Itunes Connect.
 
 Request a item list which is purchasable. This list has items which are registered in both Market(AppStore) and NHN Cloud IAP Console.
 
 @param completion      completion may return the NSArray of TCGBPurchasableItem.<br/>
 If there is an error, TCGBError will be returned.
 @warning   You should call this method after ```logged in```, otherwise you will get **TCGB_ERROR_NOT_LOGGED_IN** error in the completion.
 
 ### Usage Example
 
    - (void)viewDidLoad {
        [TCGBPurchase requestItemListPurchasableWithCompletion:^(NSArray *purchasableItemArray, TCGBError *error) {
            NSMutableArray *itemArrayMutable = [[NSMutableArray alloc] init];
            [purchasableItemArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                TCGBPurchasableItem *item = (TCGBPurchasableItem *)obj;
                 
                [itemArrayMutable addObject:item];
            }];
        }];
    }
 
 */
+ (void)requestItemListPurchasableWithCompletion:(void(^)(NSArray<TCGBPurchasableItem *> * _Nullable purchasableItemArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestItemListPurchasable(completion:));

/**---------------------------------------------------------------------------------------
 * @name Request Purchasing Item
 *  ---------------------------------------------------------------------------------------
 */

/** This is the method to request purchasing item which identifier is itemSeq. There is a viewController parameter and you may put your top most viewController. If you don't, this method will find out top most view controller and put it in the parameter.
 
 Request Purchasing Item that has itemId.
 
 @param itemSeq         itemID which you want to purchase.
 @param viewController  represent to current viewcontroller.
 @param completion      completion may return the TCGBPurchasableReceipt instance.<br/>
 If there is an error, TCGBError will be returned.
 @warning   You should call this method after ```logged in```, otherwise you will get **TCGB_ERROR_NOT_LOGGED_IN** error in the completion.
 
 ### Usage Example

    - (void)purchasingItem:(long)itemSeq {
        [TCGBPurchase requestPurchaseWithItemSeq:itemSeq viewController:self completion:^(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error) {
            if (error.code == TCGB_ERROR_PURCHASE_USER_CANCELED) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Item Purchase"
                                                                    message:[NSString stringWithFormat:@"You Canceled."]
                                                                    preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
                    [alertController addAction:defaultAction];
 
                    [parentViewController presentViewController:alertController animated:NO completion:nil];
                });
            } else if (error) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Item Purchase"
                                                                     message:[NSString stringWithFormat:@"There was an Error : %ld", (long)error.code]
                                                                     preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
                    [alertController addAction:defaultAction];
                    [parentViewController presentViewController:alertController animated:NO completion:nil];
                });
            }
        }];
    }
 
 */
+ (void)requestPurchaseWithItemSeq:(long)itemSeq
                    viewController:(UIViewController *)viewController
                        completion:(void(^)(TCGBPurchasableReceipt * _Nullable purchasableReceipt, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestPurchase(itemSeq:viewController:completion:));

/** This is the method to request purchasing item which identifier is gamebaseProductID. There is a viewController parameter and you may put your top most viewController. If you don't, this method will find out top most view controller and put it in the parameter.

Request Purchasing Item that has gamebaseProductID.

@param gamebaseProductId         gamebaseProductID which you want to purchase.
@param viewController  represent to current viewcontroller.
@param completion      completion may return the TCGBPurchasableReceipt instance.<br/>
If there is an error, TCGBError will be returned.
@warning   You should call this method after ```logged in```, otherwise you will get **TCGB_ERROR_NOT_LOGGED_IN** error in the completion.

### Usage Example

   - (void)purchasingItem:(NSString *)gamebaseProductId {
       [TCGBPurchase requestPurchaseWithGamebaseProductId:gamebaseProductId viewController:self completion:^(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error) {
           if (error.code == TCGB_ERROR_PURCHASE_USER_CANCELED) {
               dispatch_async(dispatch_get_main_queue(), ^{
                   UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Item Purchase"
                                                                   message:[NSString stringWithFormat:@"You Canceled."]
                                                                   preferredStyle:UIAlertControllerStyleAlert];
                   UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
                   [alertController addAction:defaultAction];

                   [parentViewController presentViewController:alertController animated:NO completion:nil];
               });
           } else if (error) {
               dispatch_async(dispatch_get_main_queue(), ^{
                   UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Item Purchase"
                                                                    message:[NSString stringWithFormat:@"There was an Error : %ld", (long)error.code]
                                                                    preferredStyle:UIAlertControllerStyleAlert];
                   UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
                   [alertController addAction:defaultAction];
                   [parentViewController presentViewController:alertController animated:NO completion:nil];
               });
           }
       }];
   }

*/
+ (void)requestPurchaseWithGamebaseProductId:(NSString *)gamebaseProductId
                              viewController:(UIViewController *)viewController
                                  completion:(void(^)(TCGBPurchasableReceipt * _Nullable purchasableReceipt, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestPurchase(gamebaseProductId:viewController:completion:));

/** This is the method to request purchasing item which identifier is gamebaseProductID. There is a viewController parameter and you may put your top most viewController. If you don't, this method will find out top most view controller and put it in the parameter. You can set a custom payment. After payment is completed, you will receive it throgh purchasableReceipt.
 
Request Purchasing Item that has gamebaseProductID.

@param gamebaseProductId         gamebaseProductID which you want to purchase.
@param payload         user define payload
@param viewController  represent to current viewcontroller.
@param completion      completion may return the TCGBPurchasableReceipt instance.<br/>
If there is an error, TCGBError will be returned.
@warning   You should call this method after ```logged in```, otherwise you will get **TCGB_ERROR_NOT_LOGGED_IN** error in the completion.

### Usage Example

   - (void)purchasingItem:(NSString *)gamebaseProductId payload:(NSString *)payload {
       [TCGBPurchase requestPurchaseWithGamebaseProductId:gamebaseProductId payload:payload viewController:self completion:^(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error) {
           if (error.code == TCGB_ERROR_PURCHASE_USER_CANCELED) {
               dispatch_async(dispatch_get_main_queue(), ^{
                   UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Item Purchase"
                                                                   message:[NSString stringWithFormat:@"You Canceled."]
                                                                   preferredStyle:UIAlertControllerStyleAlert];
                   UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
                   [alertController addAction:defaultAction];

                   [parentViewController presentViewController:alertController animated:NO completion:nil];
               });
           } else if (error) {
               dispatch_async(dispatch_get_main_queue(), ^{
                   UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Item Purchase"
                                                                    message:[NSString stringWithFormat:@"There was an Error : %ld", (long)error.code]
                                                                    preferredStyle:UIAlertControllerStyleAlert];
                   UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
                   [alertController addAction:defaultAction];
                   [parentViewController presentViewController:alertController animated:NO completion:nil];
               });
           }
       }];
   }

*/
+ (void)requestPurchaseWithGamebaseProductId:(NSString *)gamebaseProductId
                                     payload:(nullable NSString *)payload
                              viewController:(UIViewController *)viewController
                                  completion:(void(^)(TCGBPurchasableReceipt * _Nullable purchasableReceipt, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestPurchase(gamebaseProductId:payload:viewController:completion:));

/**---------------------------------------------------------------------------------------
 * @name Request non-consumed Item List
 *  ---------------------------------------------------------------------------------------
 */

/** This method provides an item list that have non-consumed.
 
 Request a Item List which is not consumed. You should deliver this itemReceipt to your game server to consume it or request consuming API to NHN Cloud IAP Server. You may call this method after logged in and deal with these non-consumed items.
 
 @param configuration This configuration is applied to the behavior of IAP information.
 @param completion completion may return the NSArray of TCGBPurchasableReceipt instances.<br/>
 This instance has the paymentSequence, itemSequence, PurchaseToken information.<br/>
 If there is an error, TCGBError will be returned.
 @warning   You should call this method after ```logged in```, otherwise you will get **TCGB_ERROR_NOT_LOGGED_IN** error in the completion.
 
 ### Usage Example

     - (void)viewDidLoad {
         TCGBPurchasableConfiguration *config = [[TCGBPurchasableConfiguration alloc] init];
         config.allStores = NO;
         [TCGBPurchase requestItemListOfNotConsumedWithConfiguration:config completion:^(NSArray<TCGBPurchasableReceipt *> *purchasableReceiptArray, TCGBError *error) {
             // should deal with this not-consumed items.
         }];
     }
 
 */
+ (void)requestItemListOfNotConsumedWithConfiguration:(TCGBPurchasableConfiguration *)configuration
                                           completion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestItemListOfNotConsumed(configuration:completion:));


/**---------------------------------------------------------------------------------------
 * @name Request retry purchasing processes
 *  ---------------------------------------------------------------------------------------
 */

/** This method provides item list that are currently subscribed.
 
 Request a list of payment products that are currently subscribed.
 
 @param configuration This configuration is applied to the behavior of IAP information.
 @param completion completion pass to API result.
 */
+ (void)requestActivatedPurchasesWithConfiguration:(TCGBPurchasableConfiguration *)configuration
                                        completion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestActivatedPurchases(configuration:completion:));

/** This method restore auto-renewable subscription products.

 Restores the transaction of the AppStore's auto-renewable subscription product and returns a list of active subscription products.

 @since Added 2.6.0.
 @param completion The handler to execute after the restore is complete.
 */
+ (void)requestRestoreWithCompletion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestRestore(completion:));

@end

@interface TCGBPurchase (deprecated)

/*! This is the method for obtaining ItemList which is registered at NHN Cloud IAP Console.
 
 Request a item list which is purchasable. This list has items which are only registered in NHN Cloud IAP Console, not Market(AppStore)
 
 @param completion      completion may return the NSArray of TCGBPurchasableItem.<br/>
 If there is an error, TCGBError will be returned.
 @warning   You should call this method after ```logged in```, otherwise you will get **TCGB_ERROR_NOT_LOGGED_IN** error in the completion.
 
 @deprecated As of release 2.76.0, this API is not used anymore.
 
 ### Usage Example
 
    - (void)viewDidLoad {
        [TCGBPurchase requestItemListAtIAPConsoleWithCompletion:^(NSArray *purchasableItemArray, TCGBError *error) {
            NSMutableArray *itemArrayMutable = [[NSMutableArray alloc] init];
            [purchasableItemArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                TCGBPurchasableItem *item = (TCGBPurchasableItem *)obj;
                [itemArrayMutable addObject:item];
            }];
        }];
    }
 
 */
+ (void)requestItemListAtIAPConsoleWithCompletion:(void(^)(NSArray<TCGBPurchasableItem *> * _Nullable purchasableItemArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestItemListAtIAPConsole(completion:))
    DEPRECATED_MSG_ATTRIBUTE("This API is not used anymore.");

+ (void)requestItemListOfNotConsumedWithCompletion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestItemListOfNotConsumed(completion:))
    DEPRECATED_MSG_ATTRIBUTE("Use requestItemListOfNotConsumedWithConfiguration:completion: method instead.");

/** This method is for retrying failed purchasing proccesses.
 
 Request a retrying transaction which is not completed to IAP Server
 
 @param completion      completion may return the TCGBPurchasableRetryTransactionResult which has two member variables which are named 'successList' and 'failList'.<br/>
 These two variables are array of TCGBPurchasableReceipt.<br/>
 Each key has a list of TCGBPurchasableReceipt that has uncompleted purchase information.<br/>
 If there is an error, TCGBError will be returned.
 
 @deprecated As of release 2.6.0, SDK retries transaction automatically in internal process. You don't need to call explicitly. Result is always success.
  
 ### Usage Example

    - (void)viewDidLoad {
        [TCGBPurchase requestRetryTransactionWithCompletion:^(TCGBPurchasableRetryTransactionResult *transactionResult, TCGBError *error) {
            // should deal with this retry transaction result.
            // if succeeded, you may send result to your gameserver and add item to user.
        }];
    }
 
 */
+ (void)requestRetryTransactionWithCompletion:(void(^)(TCGBPurchasableRetryTransactionResult * _Nullable transactionResult, TCGBError * _Nullableerror))completion
    DEPRECATED_MSG_ATTRIBUTE("SDK retries transaction automatically in internal process. You don't need to call explicitly. Result is always success.");

/**
 @since Added 2.6.0.
 */
+ (void)requestActivatedPurchasesWithCompletion:(void(^)(NSArray<TCGBPurchasableReceipt *> * _Nullable purchasableReceiptArray, TCGBError * _Nullable error))completion
    NS_SWIFT_NAME(requestActivatedPurchases(completion:))
    DEPRECATED_MSG_ATTRIBUTE("Use requestItemListOfNotConsumedWithConfiguration:completion: method instead.");

/**---------------------------------------------------------------------------------------
 * @name Settter and Getter Store
 *  ---------------------------------------------------------------------------------------
 */

/** This is a method for set up the store. It should be available StoreCode such as "AS". In normal cases, This method is not needed. Most of application uses "AS"(Apple AppStore) as a store.
 If not, you should set this value for using a specific store.
 
 Set a specific store for access this store.
 
 @param storeCode      storeCode represents store that item is registered and where you can buy item.
 @deprecated As of release 2.79.0, use [TCGBConfiguration configurationWithAppID:appVersion:zoneType:storeCode:] method instead.
 */
+ (void)setStoreCode:(NSString *)storeCode
    NS_SWIFT_NAME(setStoreCode(_:))
    DEPRECATED_MSG_ATTRIBUTE("As of release 2.79.0, use [TCGBConfiguration configurationWithAppID:appVersion:zoneType:storeCode:] method instead.");


/** This method returns a store code that is set up.
 
 @return storecode that is already set up.
 @deprecated As of release 2.79.0, use TCGBConfiguration.storeCode instead.
 */
+ (NSString *)storeCode
    NS_SWIFT_NAME(storeCode())
    DEPRECATED_MSG_ATTRIBUTE("As of release 2.79.0, use [TCGBConfiguration storeCode] instead.");

/**---------------------------------------------------------------------------------------
 * @name Add SKPaymentTransactionObserver to support 'App Store Promotion'
 *  ---------------------------------------------------------------------------------------
 */

/** This is a method for add observer to App Store Connect for receiving a notification - paymentQueue:shouldAddStorePayment:forProduct: -.<br/>
 If you want to deliver some items that have been purchased to user, you should implement this handler.<br/>
 You can receive a TCGBPurchasableReceipt object and receive whether error or success by callback.<br/>
 This handler return same information with 'requestPurchaseWithItemSeq:viewController:completion:'
 
 @param handler   handler may return the result of purchase by App Store Promotion.
 @warning You should call this method after ```logged in```, and you sould call this before an other APIs in TCGBPurchase.<br/>
 This method can work on iOS11 or later.
 @deprecated As of release 2.80.0, use +[TCGBGamebase addEventHandler:] method instead.
 
 ### Usage Example
 
    - (void)wantToAddTransactionObserver {
        [TCGBPurchase setPromotionIAPHandler:^(TCGBPurchasableReceipt *purchasableReceipt, TCGBError *error) {
            // should deal with this not-consumed items.
        }];
    }
 
 */
+ (void)setPromotionIAPHandler:(void(^)(TCGBPurchasableReceipt * _Nullable purchasableReceipt, TCGBError * _Nullable error))handler
    NS_SWIFT_NAME(setPromotionIAPHandler(_:))
    DEPRECATED_MSG_ATTRIBUTE("Use +[TCGBGamebase addEventHandler:] method instead.");

@end

NS_ASSUME_NONNULL_END
