#import "CheckInActionHandler.h"
#import "Lang.h"
#import "SDK.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import <BlocksKit/BlocksKit.h>
#import <BlocksKit/BlocksKit+UIKit.h>
#import "Utility.h"
#import "SalesEntry.h"
#import "SoldStock.h"
#import "BusAjaxDo.h"
#import "TicketStatusApi.h"
#import "Vars.h"

@interface CheckInActionHandler ()
@end

@implementation CheckInActionHandler

#pragma mark - Public

+ (void)updateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn commit:(void (^)(NSString *message))commit {
	[CheckInActionHandler updateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:NO blockStatus:0 commit:commit rollback:nil];
}

+ (void)updateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn commit:(void (^)(NSString *message))commit rollback:(void (^)(NSString *message))rollback {
	[CheckInActionHandler updateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:NO blockStatus:0 commit:commit rollback:rollback];
}

+ (void)updateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn blockStatus:(NSInteger)blockStatus commit:(void (^)(NSString *message))commit {
	[CheckInActionHandler updateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:YES blockStatus:blockStatus commit:commit rollback:nil];
}

+ (void)updateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn blockStatus:(NSInteger)blockStatus commit:(void (^)(NSString *message))commit rollback:(void (^)(NSString *message))rollback {
	[CheckInActionHandler updateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:YES blockStatus:blockStatus commit:commit rollback:rollback];
}

#pragma mark - Network

+ (void)updateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn isSelfCheckIn:(BOOL)isSelfCheckIn commit:(void (^)(NSString *message))commit rollback:(void (^)(NSString *message))rollback {
	UpdateStocksCheckIn *updateStocksCheckIn = [[UpdateStocksCheckIn alloc] init];
	updateStocksCheckIn.stockIds = [stocks bk_map:^NSNumber *(SoldStock *stock) {
		return @(stock.stock_id);
	}];
	updateStocksCheckIn.isCheckIn = isCheckIn;
	updateStocksCheckIn.isSelfCheckIn = isSelfCheckIn;

	NSDictionary *requestDict = [BeanUtils describeAccessible:updateStocksCheckIn];
	// NSLog(@"%@", requestDict);
	__block BOOL success = NO;
	__block NSString *message = nil;
	[Utility performRESTRequestWithMethod:@"POST" url:updateStocksCheckIn.address parameters:requestDict success:^(id jsonObject) {
		// NSLog(@"%@", jsonObject);
		WebServiceResponseJsonMapper *mapper = [[WebServiceResponseJsonMapper alloc] initWithClass:[UpdateStocksCheckInResponse class]];
        if (![mapper parseWithJSONObject:jsonObject]) {
            UpdateStocksCheckInResponse *response = mapper.response;
            if(response.errorCode > 0){
                message = response.errorMessage;
            }else{
                NSArray *boardingNumbers = response.boardingNumbers;
                [stocks enumerateObjectsUsingBlock:^(SoldStock *stock, NSUInteger idx, BOOL *stop) {
                    stock.checked = isCheckIn && !stock.vendor_checkin;
                    stock.vendor_checkin = isCheckIn;
                    if (stocks.count == boardingNumbers.count) {
                        stock.boarding_number = boardingNumbers[idx];
                    } else {
                        stock.boarding_number = nil;
                    }
                }];
                if (isSelfCheckIn) {
                    NSArray *array = [boardingNumbers bk_select:^BOOL (id obj) {
                        return ![StringUtils isEmpty:obj];
                    }];
                    if (array.count > 0) {
                        message = [NSString stringWithFormat:@"You have successfully checked into your bus! Your boarding sequence number: %@. We will also email you.", [array componentsJoinedByString:@", "]];
                    } else {
                        message = @"You have successfully checked into your bus!";
                    }
                }
                success = YES;
            }
        }
		if (success) {
			if (commit) {
				commit(message);
			}
		} else {
			if (rollback) {
				rollback(message);
			}
		}
            
	} error:^(NSError *error) {
		[CocoaUtils showNotificationWithMessage:error.localizedDescription];
		if (rollback) {
			rollback(nil);
		}
	}];
}

+ (void)updateToCheckInPendingFromStocks:(NSArray *)stocks commit:(void (^)(NSString *message))commit rollback:(void (^)(NSString *message))rollback {
	SelfCheckInPending *selfCheckInPending = [[SelfCheckInPending alloc] init];
	selfCheckInPending.stockIds = [[stocks valueForKeyPath:@"stock_id"] componentsJoinedByString:@","];

	NSDictionary *requestDict = [BeanUtils describeAccessibleSimple:selfCheckInPending];

	__block BOOL success = NO;
	__block NSString *message = nil;
	[Utility performRESTRequestWithMethod:@"GET" url:selfCheckInPending.address parameters:requestDict success:^(id jsonObject) {
		WebServiceResponseJsonMapper *mapper = [[WebServiceResponseJsonMapper alloc] initWithClass:[SelfCheckInPendingResponse class]];
		if (![mapper parseWithJSONObject:jsonObject]) {
			SelfCheckInPendingResponse *response = mapper.response;
			if (response.success) {
				message = @"We kindly ask that you arrive at the bus stop with your e-ticket and photo ID 30 minutes prior to your scheduled departure time.";
				success = YES;
			}
		}
		if (success) {
			if (commit) {
				commit(message);
			}
		} else {
			if (rollback) {
				rollback(message);
			}
		}
	} error:^(NSError *error) {
		[CocoaUtils showNotificationWithMessage:error.localizedDescription];
		if (rollback) {
			rollback(nil);
		}
	}];
}

#pragma mark - Private

+ (void)updateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn isSelfCheckIn:(BOOL)isSelfCheckIn blockStatus:(NSInteger)blockStatus commit:(void (^)(NSString *message))commit rollback:(void (^)(NSString *message))rollback {
	[self internallyUpdateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:isSelfCheckIn blockStatus:(NSInteger)blockStatus commit:commit rollback:rollback];
}

+ (void)internallyUpdateStocks:(NSArray *)stocks toCheckIn:(BOOL)isCheckIn isSelfCheckIn:(BOOL)isSelfCheckIn blockStatus:(NSInteger)blockStatus commit:(void (^)(NSString *message))commit rollback:(void (^)(NSString *message))rollback {
	if (isSelfCheckIn) {
		BOOL canSelfCheckIn = [stocks bk_any:^BOOL (SoldStock *stock) {
			return [[[DateFormatUtils ISO_DATE_FORMAT] parse:stock.service_date] compare:[DateUtils addHours:[NSDate date] amount:24]] != NSOrderedDescending;
		}];
		if (!canSelfCheckIn) {
			if (rollback) {
				rollback(@"It's too early to check in for your bus. Please try again within 24 hours prior to your scheduled departure time.");
			}
		} else {
			if (blockStatus == 1 || blockStatus == 2) {
				[CheckInActionHandler updateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:isSelfCheckIn commit:commit rollback:rollback];
			} else {
				[CheckInActionHandler updateToCheckInPendingFromStocks:stocks commit:commit rollback:rollback];
			}
		}
	} else {
		[CheckInActionHandler updateStocks:stocks toCheckIn:isCheckIn isSelfCheckIn:isSelfCheckIn commit:commit rollback:rollback];
	}
}

@end
