//
// CreditCardDetailViewController.m
// Project
//
// Created by Ziv on 16/5/30.
//
//

#import "CreditCardDetailViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "CocoaUtils.h"
#import "DrawUtils.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import "PrivacyUtils.h"
#import <libextobjc/EXTScope.h>
#import <LoremIpsum/LoremIpsum.h>
#import "Utility.h"
#import "CreditCardListViewController.h"
#import "Vars.h"

NSString *const CreditCardDidInsertNotification = @"CreditCardDidInsertNotification";
NSString *const CreditCardDidUpdateNotification = @"CreditCardDidUpdateNotification";
NSString *const CreditCardDidDeleteNotification = @"CreditCardDidDeleteNotification";
NSString *const CreditCardDefaultIdUserInfoKey = @"CreditCardDefaultIdUserInfoKey";

@interface CreditCardDetailViewController ()

@property (nonatomic, copy) CreditCard *creditCard;

@property (nonatomic, copy) void (^didInsertBlock) (CreditCard *creditCard);
@property (nonatomic, copy) void (^didUpdateBlock) (CreditCard *creditCard);
@property (nonatomic, copy) void (^didDeleteBlock) (CreditCard *creditCard);

@property (nonatomic, strong) NSArray *cellDataArrays;

@property (nonatomic, assign, readonly) BOOL allowsSimulate;

@end

@implementation CreditCardDetailViewController

- (instancetype)initWithCreditCard:(CreditCard *)creditCard {
	if (self = [self init]) {
		self.creditCard = creditCard;
	}
	return self;
}

- (instancetype)init {
	if (self = [super init]) {
		self.title = @"";
		[[Vars appDelegate] applyDefaultConfigurationForViewController:self];
	}
	return self;
}

- (void)viewDidLoad {
	[super viewDidLoad];

	BOOL isExisted = self.creditCard.ccid > 0;
	if (isExisted) {
		self.title = [NSString stringWithFormat:IMLocalizedString(@"Edit %@"), IMLocalizedString(@"Credit Card")];
	} else {
		self.title = [NSString stringWithFormat:IMLocalizedString(@"Add %@"), IMLocalizedString(@"Credit Card")];
	}
	if (isExisted) {
		self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(removeCreditCard)];
	}

	if (YES) {
		UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), [UIConstants defaultTableViewRowHeight] + 15 * 2)];
		UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
		button.frame = CGRectMake(15, 15, CGRectGetWidth([UIScreen mainScreen].bounds) - 15 * 2, [UIConstants defaultTableViewRowHeight]);
		button.backgroundColor = [Vars defaultTintColor];
		button.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont buttonFontSize]];
		[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		[button setTitle:IMLocalizedString(@"Save") forState:UIControlStateNormal];
		[button addTarget:self action:@selector(footerButtonAction) forControlEvents:UIControlEventTouchUpInside];
		[Utility addRoundedBorderToButton:button];
		[footerView addSubview:button];
		self.tableView.tableFooterView = footerView;
	}
	self.tableView.sectionHeaderHeight = [UIConstants defaultTableViewCellLayoutInsets].top;
	self.tableView.sectionFooterHeight = [UIConstants defaultTableViewCellLayoutInsets].bottom;
	[self buildCellDataSource];
}

- (void)viewWillAppear:(BOOL)animated {
	[super viewWillAppear:animated];

	[CardIOUtilities preload];
}

#pragma mark - Property

- (CreditCard *)creditCard {
	if (!_creditCard) {
		_creditCard = self.allowsSimulate ? [CreditCard randomCreditCard] : [[CreditCard alloc] init];
		_creditCard.transient = self.allowsTransient;
	}
	return _creditCard;
}

- (BOOL)allowsSimulate {
#if DEBUG
	return [Vars is_develop];
#else
	return NO;
#endif
}

#pragma mark - Network

- (void)updateCreditCard {
	BOOL isExisted = self.creditCard.ccid > 0;

	if (self.creditCard.transient) {
		if (!isExisted) {
			self.creditCard.ccid = abs((int32_t)[LoremIpsum word].hash);
		}
		[self sendActionToUpdateCreditCard:self.creditCard withDefaultId:-1 isExisted:isExisted];
		return;
	}

	UpdateCreditCard *updateCreditCard = [[UpdateCreditCard alloc] init];
	updateCreditCard.creditCardDetails = self.creditCard;

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

	[Utility getXMLFromRequestWithMethod:@"GET" url:updateCreditCard.address parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		WebServiceResponseJsonMapper *mapper = [[WebServiceResponseJsonMapper alloc] initWithClass:[UpdateCreditCardResponse class]];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			UpdateCreditCardResponse *response = mapper.response;
			if (response.error_code > 0) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error_message];
			} else {
				if (!isExisted) {
					self.creditCard.ccid = response.ccid;
				}
				[self sendActionToUpdateCreditCard:self.creditCard withDefaultId:response.default_ccid isExisted:isExisted];
			}
		}
	}];
}

- (void)removeCreditCard {
	if (self.creditCard.transient) {
		[self sendActionToDeleteCreditCard:self.creditCard withDefaultId:-1];
		return;
	}

	RemoveCreditCard *removeCreditCard = [[RemoveCreditCard alloc] init];
	removeCreditCard.ccid = self.creditCard.ccid;

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

	[Utility getXMLFromRequestWithMethod:@"GET" url:removeCreditCard.address parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		WebServiceResponseJsonMapper *mapper = [[WebServiceResponseJsonMapper alloc] initWithClass:[RemoveCreditCardResponse class]];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			RemoveCreditCardResponse *response = mapper.response;
			if (response.error_code > 0) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error_message];
			} else {
				[self sendActionToDeleteCreditCard:self.creditCard withDefaultId:response.default_ccid];
			}
		}
	}];
}

#pragma mark - Action

- (void)footerButtonAction {
	if ([self validateCreditCard]) {
		[self updateCreditCard];
	}
}

#pragma mark - Private

- (void)buildCellDataSource {
	NSMutableArray *arrays = [NSMutableArray array];
	if (!self.allowsTransient) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.style = UITableViewCellStyleValue1;
		data.editingType = TableViewCellEditingTypeSwitch;
		data.text = IMLocalizedString(@"Remember this card");
		data.keyPath = @"persistent";
		data.observedObject = self.creditCard;
		[arrays addObject:@[data]];
	}
	[arrays addObject:[Utility collectTableViewCellDataArrayWithCreditCard:self.creditCard]];
	if (self.allowsDefault) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.style = UITableViewCellStyleValue1;
		data.editingType = TableViewCellEditingTypeSwitch;
		data.text = IMLocalizedString(@"Default");
		data.keyPath = @"isDefault";
		data.observedObject = self.creditCard;
		[arrays addObject:@[data]];
	}
	if (NO) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.text = IMLocalizedString(@"Any information you provide will only be used for processing your order and will not be sold, rented, leased or forwarded to any third party.");
		data.allowsTextLineWrapping = YES;
		[arrays addObject:@[data]];
	}
	self.cellDataArrays = [NSArray arrayWithArray:arrays];
}

- (BOOL)validateCreditCard {
	[self.tableView endEditing:YES];
	for (int section = 0; section < self.cellDataArrays.count; section++) {
		for (int row = 0; row < [self.cellDataArrays[section] count]; row++) {
			NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
			TableViewCellData *data = self.cellDataArrays[section][row];
			if (![data validateRequired]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:[data requiredValidationMessage:NO] dismissalHandler:^{
					[UIToolkit tableView:self.tableView atIndexPath:indexPath didFocusWithData:data];
				}];
				return NO;
			}
			if (![data validateIntegrity]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:[data integrityValidationMessage:NO] dismissalHandler:^{
					[UIToolkit tableView:self.tableView atIndexPath:indexPath didFocusWithData:data];
				}];
				return NO;
			}
		}
	}
	return YES;
}

- (void)sendActionToUpdateCreditCard:(CreditCard *)creditCard withDefaultId:(NSInteger)defaultId isExisted:(BOOL)isExisted {
	NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
	[notificationCenter postNotificationName:isExisted ? CreditCardDidUpdateNotification : CreditCardDidInsertNotification object:creditCard userInfo:defaultId >= 0 ? @{ CreditCardDefaultIdUserInfoKey : @(defaultId) } : nil];
	if (isExisted) {
		if (self.didUpdateBlock) {
			self.didUpdateBlock(creditCard);
		}
	} else {
		if (self.didInsertBlock) {
			self.didInsertBlock(creditCard);
		}
	}
}

- (void)sendActionToDeleteCreditCard:(CreditCard *)creditCard withDefaultId:(NSInteger)defaultId {
	NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
	[notificationCenter postNotificationName:CreditCardDidDeleteNotification object:creditCard userInfo:defaultId >= 0 ? @{ CreditCardDefaultIdUserInfoKey : @(defaultId) } : nil];
	if (self.didDeleteBlock) {
		self.didDeleteBlock(creditCard);
	}
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return self.cellDataArrays.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	return [self.cellDataArrays[section] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArrays[indexPath.section][indexPath.row];
	return [UIToolkit tableView:tableView atIndexPath:indexPath cellWithData:data];
}

#pragma mark - Table view delegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArrays[indexPath.section][indexPath.row];
	return [UIToolkit tableView:tableView atIndexPath:indexPath rowHeightWithData:data];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
	TableViewCellData *data = self.cellDataArrays[indexPath.section][indexPath.row];
	[UIToolkit tableView:tableView atIndexPath:indexPath didSelectWithData:data];
}

@end
