//
// SecurityVerificationViewController.m
// Project
//
// Created by ziv on 2017/9/29.
//

#import "SecurityVerificationViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "CocoaUtils.h"
#import "ContactsManager.h"
#import "DrawUtils.h"
#import "ImageUtils.h"
#import "NetUtils.h"
#import "LandscapeNavigationController.h"
#import "TableViewCellWrapper.h"
#import "UIConstants.h"
#import "CardIOPaymentViewControllerDelegateImpl.h"
#import <BlocksKit/BlocksKit+UIKit.h>
#import <CardIO.h>
#import <libextobjc/EXTScope.h>
#import <MBProgressHUD/MBProgressHUD.h>
#import <UberSignature/UBSignatureDrawingViewController.h>
#import <YYText/YYText.h>
#import "Utility.h"
#import "BookingFinishViewController.h"
#import "Vars.h"

@interface SecurityVerificationViewController () <UBSignatureDrawingViewControllerDelegate>

@property (nonatomic, weak) IBOutlet TableViewCellWrapper *firstHeaderWrapper;
@property (nonatomic, weak) IBOutlet TableViewCellWrapper *secondHeaderWrapper;
@property (nonatomic, weak) IBOutlet TableViewCellWrapper *thirdHeaderWrapper;
@property (nonatomic, weak) IBOutlet UIButton *cardFrontButton;
@property (nonatomic, weak) IBOutlet UIButton *photoIdButton;
@property (nonatomic, weak) IBOutlet UIButton *signatureButton;
@property (nonatomic, weak) IBOutlet UIImageView *checkmarkImageView;
@property (nonatomic, weak) IBOutlet UILabel *authorizationLabel;
@property (nonatomic, weak) IBOutlet YYLabel  *agreementLabel;
@property (nonatomic, weak) IBOutlet UILabel *signature1Label;
@property (nonatomic, weak) IBOutlet UILabel *signature2Label;
@property (nonatomic, weak) IBOutlet UILabel *signature3Label;
@property (nonatomic, weak) IBOutlet UIButton *submitButton;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *firstHeightConstraint;

@property (nonatomic, copy) void (^destructiveBlock) (void);
@property (nonatomic, strong) UIImage *cardFrontImage;
@property (nonatomic, strong) UIImage *photoIdImage;
@property (nonatomic, strong) UIImage *signatureImage;
@property (nonatomic, strong) NSString *cardFrontImgName;
@property (nonatomic, strong) NSString *photoIdImgName;
@property (nonatomic, strong) NSString *signatureImgName;

- (IBAction)performActionForVerifyCreditCard;

@end

@implementation SecurityVerificationViewController

- (instancetype)init {
	if (self = [super init]) {
		self.title = IMLocalizedString(@"Credit Card Verification");
		self.hidesBottomBarWhenPushed = YES;
		[[Vars appDelegate] applyDefaultConfigurationForViewController:self];
	}
	return self;
}

- (void)viewDidLoad {
	[super viewDidLoad];

	self.firstHeaderWrapper.style = UITableViewCellStyleSubtitle;
	[self.firstHeaderWrapper get].textLabel.numberOfLines = 0;
	[self.firstHeaderWrapper get].textLabel.text = [NSString stringWithFormat:@"1. %@", IMLocalizedString(@"Please upload your pictures of credit card front side here:")];
	[self.firstHeaderWrapper get].detailTextLabel.numberOfLines = 0;
	[self.firstHeaderWrapper get].detailTextLabel.text = IMLocalizedString(@"Please make sure that the card number, the name on the card and the expiration date are visible.");
	if (YES) {
		[self.firstHeaderWrapper get].textLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.firstHeaderWrapper.frame) - [UIConstants defaultTableViewCellLayoutInsets].left - [UIConstants defaultTableViewCellLayoutInsets].right;
		[self.firstHeaderWrapper get].detailTextLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.firstHeaderWrapper.frame) - [UIConstants defaultTableViewCellLayoutInsets].left - [UIConstants defaultTableViewCellLayoutInsets].right;
		self.firstHeightConstraint.constant = MAX([self.firstHeaderWrapper get].textLabel.intrinsicContentSize.height + [self.firstHeaderWrapper get].detailTextLabel.intrinsicContentSize.height + [UIConstants defaultTableViewCellLayoutInsets].top + [UIConstants defaultTableViewCellLayoutInsets].bottom, [UIConstants defaultTableViewRowHeight]);
	}
	[self.secondHeaderWrapper get].textLabel.numberOfLines = 0;
	[self.secondHeaderWrapper get].textLabel.text = [NSString stringWithFormat:@"2. %@", IMLocalizedString(@"Please upload your picture of ID Card here:")];
	[self.thirdHeaderWrapper get].textLabel.numberOfLines = 0;
	[self.thirdHeaderWrapper get].textLabel.text = [NSString stringWithFormat:@"3. %@", IMLocalizedString(@"Credit card authorization agreement")];

	[DrawUtils addSolidBorderToRect:self.cardFrontButton strokeColor:[Vars defaultTintColor]];
	[DrawUtils addSolidBorderToRect:self.photoIdButton strokeColor:[Vars defaultTintColor]];
	[DrawUtils addSolidBorderToRect:self.signatureButton strokeColor:[Vars defaultTintColor]];

	[self reloadButtonDefault:self.cardFrontButton];
	[self.cardFrontButton addTarget:self action:@selector(performSegueForReadCardOnButton:) forControlEvents:UIControlEventTouchUpInside];

	[self reloadButtonDefault:self.photoIdButton];
	[self.photoIdButton addTarget:self action:@selector(performSegueForReadCardOnButton:) forControlEvents:UIControlEventTouchUpInside];

	[self reloadButtonDefault:self.signatureButton];
	[self.signatureButton addTarget:self action:@selector(performSegueForSignature) forControlEvents:UIControlEventTouchUpInside];

	if (self.order) {
		NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:[NSString stringWithFormat:IMLocalizedString(@"I %@ hereby authorize %@ the use of my card to be charged in conjunction with the following information:"), self.order.credit_card.name_on_card, [Vars site_title]]]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\u2022 "]];
		if (YES) {
			NSMutableString *string = [NSMutableString string];
			[string im_appendString:IMLocalizedString(@"Order ID")];
			[string im_appendString:IMLocalizedString(PUNCTUATION_COLON)];
			[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
			[string im_appendString:self.order.order_code];
			[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:string]];
		}
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\u2022 "]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:[NSString stringWithFormat:IMLocalizedString(@"Amount to be charged: %@"), [Utility currencyStringFromNumber:self.order.payment_total_amount currencyCode:self.order.payment_currency_code]]]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\u2022 "]];
		if (YES) {
			NSMutableString *string = [NSMutableString string];
			[string im_appendString:IMLocalizedString(@"Traveler Name")];
			[string im_appendString:IMLocalizedString(PUNCTUATION_COLON)];
			[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
			[string im_appendString:[[[Sales toStocks:@[self.order]] valueForKeyPath:@"sold_to_name"] componentsJoinedByString:[StringUtils join:IMLocalizedString(PUNCTUATION_COMMA), IMLocalizedString(WORD_DIVIDER_SPACE), nil]]];
			[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:string]];
		}
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\u2022 "]];
		if (YES) {
			CMPostalAddress *billingAddress = [[CMPostalAddress alloc] init];
			billingAddress.street = self.order.credit_card.address.street;
			billingAddress.city = self.order.credit_card.address.city;
			if (![StringUtils isEmpty:self.order.credit_card.address.state]) {
				billingAddress.state = self.order.credit_card.address.state;
			} else if (![StringUtils isEmpty:self.order.credit_card.address.other_state]) {
				billingAddress.state = self.order.credit_card.address.other_state;
			}
			billingAddress.postalCode = self.order.credit_card.address.zipcode;
			billingAddress.ISOCountryCode = self.order.credit_card.address.country.uppercaseString;
			CMPostalAddressFormatter *addressFormatter = [[CMPostalAddressFormatter alloc] init];
			[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:[NSString stringWithFormat:IMLocalizedString(@"Card holder's billing address: %@"), [[addressFormatter stringFromPostalAddress:billingAddress] stringByReplacingOccurrencesOfString:@"\n" withString:@" "]]]];
		}
		self.authorizationLabel.attributedText = attributedString;
	}

	if ([Vars is_bus_site]) {
		self.checkmarkImageView.image = [DrawUtils imageWithFAKIcon:[FAKFontAwesome checkSquareOIconWithSize:CGRectGetHeight(self.checkmarkImageView.frame)] fillColor:[Vars defaultTintColor]];

		self.agreementLabel.numberOfLines = 0;
		self.agreementLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.agreementLabel.frame);

		NSString *titleString = [NSString stringWithFormat:IMLocalizedString(@"Before placing my booking online, I have read the %@ User Agreement as well as the Cancellation and Refund Policy, and agree with all the terms of the above Ordinances."), [Vars site_name]];
		NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] im_initWithString:titleString];
		[attributeString yy_setTextHighlightRange:[titleString rangeOfString:IMLocalizedString(@"User Agreement")] color:[UIColor blueColor] backgroundColor:[UIColor whiteColor] tapAction:^(UIView *_Nonnull containerView, NSAttributedString *_Nonnull text, NSRange range, CGRect rect) {
			[self performRequestForGetPageContentWithRelativeUrl:@"/useragreement/" title:IMLocalizedString(@"User Agreement")];
		}];
		[attributeString yy_setTextHighlightRange:[titleString rangeOfString:IMLocalizedString(@"Cancellation and Refund Policy")] color:[UIColor blueColor] backgroundColor:[UIColor whiteColor] tapAction:^(UIView *_Nonnull containerView, NSAttributedString *_Nonnull text, NSRange range, CGRect rect) {
			[self performRequestForGetPageContentWithRelativeUrl:@"/busgeneralinfo/" title:IMLocalizedString(@"Cancellation and Refund Policy")];
		}];
		self.agreementLabel.attributedText = attributeString;
		self.agreementLabel.font = self.authorizationLabel.font;
	}

	self.signature1Label.text = IMLocalizedString(@"By signing below, I verify my acknowledgement of the charges described above to be placed on my credit card.");
	self.signature2Label.text = IMLocalizedString(@"Card holder's signature");
	self.signature3Label.text = [NSString stringWithFormat:IMLocalizedString(@"Date: %@"), [[DateFormatUtils ISO_DATE_FORMAT] format:[NSDate date]]];

	self.submitButton.backgroundColor = [Vars defaultTintColor];
	[self.submitButton setTitle:IMLocalizedString(@"Submit") forState:UIControlStateNormal];
	[Utility addRoundedBorderToButton:self.submitButton];
}

#pragma mark - Action

- (IBAction)performActionForVerifyCreditCard {
	if (!self.cardFrontImage) {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:IMLocalizedString(@"Please take picture of credit card first")];
		return;
	}
	if (!self.photoIdImage) {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:IMLocalizedString(@"Please take picture of ID Card first")];
		return;
	}
	if (!self.signatureImage) {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:IMLocalizedString(@"Please signature first")];
		return;
	}
	if (!self.cardFrontImgName || !self.photoIdImgName || !self.signatureImgName) {
		[CocoaUtils showConfirmWithTitle:IMLocalizedString(@"Information") message:IMLocalizedString(@"An error occurred, please try again.") otherActionTitle:IMLocalizedString(@"Retry Upload") otherActionHandler:^{
			[NetUtils beginTransation];
			NSMutableArray *batchOf = [NSMutableArray array];
			if (!self.cardFrontImgName) {
				[batchOf addObject:[self performRequestForUploadImageOnButton:self.cardFrontButton progress:NO]];
			}
			if (!self.photoIdImgName) {
				[batchOf addObject:[self performRequestForUploadImageOnButton:self.photoIdButton progress:NO]];
			}
			if (!self.signatureImgName) {
				[batchOf addObject:[self performRequestForUploadImageOnButton:self.signatureButton progress:NO]];
			}
			[CocoaUtils showBusyIndicator:self.view];
			[NetUtils performBatchOf:batchOf completion:^{
				[CocoaUtils hideBusyIndicator:self.view];
				[self performActionForVerifyCreditCard];
			}];
		}];
	} else {
		[self performRequestForVerifyCreditCard];
	}
}

#pragma mark - Network

- (id)performRequestForUploadImageOnButton:(UIButton *)button progress:(BOOL)progress {
	MBProgressHUD *hud = nil;
	if (progress) {
		hud = [MBProgressHUD HUDForView:button];
		if (!hud) {
			hud = [[MBProgressHUD alloc] initWithView:button];
		}
		hud.mode = MBProgressHUDModeDeterminate;
	}

	NSDictionary *requestDict = @{ @"type" : @"upload_ccv_image", @"order_code" : self.order ? self.order.order_code : @0, @"image_type" : [self uploadImageType:button] };

	[NetUtils adviceSettings:@{ NetworkSettingResponseDecoding : @([Vars charset]), NetworkSettingResponseDataType : @"TEXT" }];
	return [Utility performUploadMultipartRequestConstructingBodyWithBlock:^(id < AFMultipartFormData > formData) {
		if (button == self.cardFrontButton) {
			[formData appendPartWithFileData:UIImageJPEGRepresentation(self.cardFrontImage, 1) name:@"image_file" fileName:[self uploadImageName:button] mimeType:@"image/jpeg"];
		} else if (button == self.photoIdButton) {
			[formData appendPartWithFileData:UIImageJPEGRepresentation(self.photoIdImage, 1) name:@"image_file" fileName:[self uploadImageName:button] mimeType:@"image/jpeg"];
		} else if (button == self.signatureButton) {
			[formData appendPartWithFileData:UIImagePNGRepresentation(self.signatureImage) name:@"image_file" fileName:[self uploadImageName:button] mimeType:@"image/png"];
		}
	} progress:hud ? ^(CGFloat progress) {
		hud.progress = progress;
	} : nil url:[Utility perlCgiBin:@"ajax"] parameters:requestDict beforeSend:^{
		self.submitButton.enabled = NO;
		button.enabled = NO;
		[hud showAnimated:YES];
	} success:^(NSString *text) {
		if ([StringUtils isEmpty:text]) {
			[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:[Vars responseException]];
		} else if (button == self.cardFrontButton) {
			self.cardFrontImgName = text;
		} else if (button == self.photoIdButton) {
			self.photoIdImgName = text;
		} else if (button == self.signatureButton) {
			self.signatureImgName = text;
		}
	} complete:^{
		[hud hideAnimated:YES];
		button.enabled = YES;
		self.submitButton.enabled = YES;
	}];
}

- (void)performRequestForVerifyCreditCard {
	VerifyCreditCard *verifyCreditCard = [[VerifyCreditCard alloc] init];
	verifyCreditCard.orderCode = self.order.order_code;
	verifyCreditCard.cardFront = self.cardFrontImgName;
	verifyCreditCard.photoId = self.photoIdImgName;
	verifyCreditCard.signature = self.signatureImgName;

	NSDictionary *requestDict = [Utility perlParamXml:[verifyCreditCard innerXML] action:verifyCreditCard.name];

	[Utility getXMLFromRequestWithMethod:@"GET" url:verifyCreditCard.address parameters:requestDict success:^(NSString *xml) {
		// NSLog(@"%@", xml);
		if (self.destructiveBlock) {
			self.destructiveBlock();
		}
	}];
}

- (void)performRequestForGetPageContentWithRelativeUrl:(NSString *)pageUrl title:(NSString *)title {
	GetPageContent *getPageContent = [[GetPageContent alloc] init];
	getPageContent.apiVersion = 0;
	getPageContent.pageUrl = pageUrl;

	NSDictionary *requestDic = [Utility perlParamXml:[getPageContent innerXML] action:getPageContent.name];

	[Utility getXMLFromRequestWithMethod:@"GET" url:getPageContent.address parameters:requestDic success:^(NSString *xml) {
		NSString *responseStr = xml;
		WebServiceResponseJsonMapper *mapper = [[WebServiceResponseJsonMapper alloc] initWithClass:[GetPageContentResponse class]];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			GetPageContentResponse *response = mapper.response;
			if (response.error_code > 0) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error_message];
			} else {
				[self performSegueForGetPageContentWithHtmlString:response.html_string baseUrl:response.base_url title:title];
			}
		}
	}];
}

#pragma mark - Segue

- (void)performSegueForReadCardOnButton:(UIButton *)button {
	if (TARGET_IPHONE_SIMULATOR) {
		return;
	}
	if (![CardIOUtilities canReadCardWithCamera]) {
		[CocoaUtils showConfirmWithTitle:IMLocalizedString(@"Information") message:[NSString stringWithFormat:IMLocalizedString(@"Please allow \"%@\" to access your camera"), [CocoaUtils bundleName]] otherActionTitle:IMLocalizedString(@"Open Settings") otherActionHandler:^{
			[CocoaUtils openSettings];
		}];
		return;
	}
	CardIOPaymentViewControllerDelegateImpl *impl = [CardIOPaymentViewControllerDelegateImpl sharedInstance];
	[impl setUserDidProvideCreditCardInfoBlock:^(CardIOCreditCardInfo *cardInfo) {
		if (cardInfo.cardImage) {
			if (button == self.cardFrontButton) {
				self.cardFrontImage = cardInfo.cardImage;
			} else if (button == self.photoIdButton) {
				self.photoIdImage = cardInfo.cardImage;
			}
			[button setBackgroundImage:cardInfo.cardImage forState:UIControlStateNormal];
			[button setImage:[DrawUtils imageWithFAKIcon:[FAKFontAwesome undoIconWithSize:32] fillColor:[Vars defaultTintColor]] forState:UIControlStateNormal];
			[self performRequestForUploadImageOnButton:button progress:YES];
		}
	}];
	CardIOPaymentViewController *viewController = [[CardIOPaymentViewController alloc] initWithPaymentDelegate:impl];
	viewController.languageOrLocale = [CocoaUtils applicationLocale].localeIdentifier;
	viewController.guideColor = [Vars defaultTintColor];
	viewController.hideCardIOLogo = YES;
	viewController.detectionMode = CardIODetectionModeCardImageOnly;
	viewController.disableManualEntryButtons = YES;
	[self presentViewController:viewController animated:YES completion:nil];
}

- (void)performSegueForSignature {
	if (TARGET_IPHONE_SIMULATOR) {
		return;
	}
	UBSignatureDrawingViewController *viewController = [[UBSignatureDrawingViewController alloc] init];
	viewController.title = IMLocalizedString(@"Signature");
	viewController.delegate = self;
	viewController.view.backgroundColor = [UIColor whiteColor];

	UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] im_initWithBarButtonSystemItem:UIBarButtonSystemItemCancel handler:^(id sender) {
		[self dismissViewControllerAnimated:YES completion:nil];
	}];
	@weakify(viewController)
	UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] im_initWithBarButtonSystemItem:UIBarButtonSystemItemDone handler:^(id sender) {
		@strongify(viewController)
		if (!viewController.isEmpty) {
			self.signatureImage = viewController.fullSignatureImage;
			[self dismissViewControllerAnimated:YES completion:^{
				[self.signatureButton setBackgroundImage:self.signatureImage forState:UIControlStateNormal];
				[self.signatureButton setImage:[DrawUtils imageWithFAKIcon:[FAKFontAwesome undoIconWithSize:32] fillColor:[Vars defaultTintColor]] forState:UIControlStateNormal];
				[self performRequestForUploadImageOnButton:self.signatureButton progress:YES];
			}];
		}
	}];
	doneItem.enabled = NO;
	UIBarButtonItem *resetItem = [[UIBarButtonItem alloc] bk_initWithBarButtonSystemItem:UIBarButtonSystemItemRedo handler:^(id sender) {
		@strongify(viewController)
		[viewController reset];
	}];
	viewController.navigationItem.leftBarButtonItem = cancelItem;
	viewController.navigationItem.rightBarButtonItems = @[doneItem, resetItem];

	LandscapeNavigationController *navigationController = [[LandscapeNavigationController alloc] initWithRootViewController:viewController];
	[self presentViewController:navigationController animated:YES completion:nil];
}

- (void)performSegueForGetPageContentWithHtmlString:(NSString *)htmlString baseUrl:(NSString *)urlString title:(NSString *)title {
	IMWebViewController *webViewController = [[IMWebViewController alloc] initWithHTMLString:htmlString baseUrl:[NSURL URLWithString:urlString]];
	webViewController.title = title;
	[[Vars appDelegate] applyDefaultConfigurationForViewController:webViewController];
	webViewController.webContainerInset = UIEdgeInsetsMake(15, 15, 15, 15);
	[self.navigationController pushViewController:webViewController animated:YES];
}


#pragma mark - Private

- (NSString *)uploadImageType:(UIButton *)button {
	if (button == self.cardFrontButton) {
		return @"front_side";
	} else if (button == self.photoIdButton) {
		return @"photo_id";
	} else if (button == self.signatureButton) {
		return @"signature";
	}
	return nil;
}

- (NSString *)uploadImageName:(UIButton *)button {
	if (button == self.cardFrontButton) {
		return @"front_side.jpg";
	} else if (button == self.photoIdButton) {
		return @"photo_id.jpg";
	} else if (button == self.signatureButton) {
		return @"signature.png";
	}
	return nil;
}

- (void)reloadButtonDefault:(UIButton *)button {
	FAKIcon *icon = nil;
	if (button == self.cardFrontButton) {
		icon = [FAKFontAwesome creditCardIconWithSize:100];
	} else if (button == self.photoIdButton) {
		icon = [FAKFontAwesome idCardOIconWithSize:100];
	}
	if (icon) {
		[button setBackgroundImage:[ImageUtils drawImage:[DrawUtils imageWithFAKIcon:icon fillColor:[UIColor silverColor]] atRect:CGRectMake((CGRectGetWidth(button.frame) - icon.iconFontSize) / 2, (CGRectGetHeight(button.frame) - icon.iconFontSize) / 2, CGRectGetWidth(button.frame), CGRectGetHeight(button.frame))] forState:UIControlStateNormal];
	}
	[button setImage:[DrawUtils imageWithFAKIcon:[FAKFontAwesome plusCircleIconWithSize:32] fillColor:[Vars defaultTintColor]] forState:UIControlStateNormal];
}

#pragma mark - <UBSignatureDrawingViewControllerDelegate>

- (void)signatureDrawingViewController:(UBSignatureDrawingViewController *)signatureDrawingViewController isEmptyDidChange:(BOOL)isEmpty {
	UIBarButtonItem *doneItem = signatureDrawingViewController.navigationItem.rightBarButtonItems[0];
	doneItem.enabled = !isEmpty;
}

@end
