//
// CheckoutViewController.m
// GotoBus
//
// Created by vae on 2018/1/15.
//

#import "CheckoutViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import "ContactsManager.h"
#import "DrawUtils.h"
#import "ImageUtils.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import "CalendarViewController.h"
#import <BlocksKit/BlocksKit.h>
#import <libextobjc/EXTScope.h>
#import <PureLayout/PureLayout.h>
#import "DZNEmptyDataSetDefault.h"
#import "Utility.h"
#import "BusAjaxDo.h"
#import "WebService.h"
#import "ScheduleAPI.h"
#import "BookGoodsResponseJsonMapper.h"
#import "CheckAvailabilityAndPricesResponseJsonMapper.h"
#import "GetPricesResponseJsonMapper.h"
// #import "CheckoutPriceView.h"
#import "Vars.h"

@interface CheckoutViewController ()
@property (nonatomic, strong) NSArray *cellDataArrays;
@property (nonatomic, strong) CartEntry *entry;
@property (nonatomic, assign) CGFloat totalPrice;
@end

@implementation CheckoutViewController

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

- (void)viewDidLoad {
	[super viewDidLoad];

	self.entry = [[CartEntry alloc] init];
	self.entry.product.product_id = self.bookingReportDetail.pid;
	self.entry.options[@"date"] = self.service_date;
	self.entry.options[@"departure"] = [NSString stringWithFormat:@"%d", self.bookingReportDetail.departureScheduleStop.id];
	self.entry.options[@"arrival"] = [NSString stringWithFormat:@"%d", self.bookingReportDetail.arrivalScheduleStop.id];

	if (YES) {
		UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
		button.frame = CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), [UIConstants defaultTableViewRowHeight]);
		button.backgroundColor = [Vars defaultTintColor];
		button.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont buttonFontSize]];
		[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		[button setTitle:@"Save" forState:UIControlStateNormal];
		[button addTarget:self action:@selector(performActionForBookBus) forControlEvents:UIControlEventTouchUpInside];
		[Utility addInsetToFooterViewIfSafeArea:button];
		self.fixedFooterView = button;
	}
}

- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	// ajax
	if (!self.entry.product.PPLBasedPrice || self.entry.peopleCount == 0) {
		[self performRequestForGetPrices];
	}
}

#pragma mark - Action

- (void)performActionForBookBus {
	if ([self performValidationForBookBus]) {
		[self performRequestForBookBus];
	}
}

#pragma mark - Network

- (void)performRequestForGetPrices {
	GetPrices *getPrices = [[GetPrices alloc] init];
	getPrices.pids = [NSString stringWithFormat:@"%d", self.bookingReportDetail.pid];
	getPrices.service_date = self.service_date;

	NSDictionary *requestDict = [BeanUtils describeAccessibleSimple:getPrices];

	[Utility performRESTRequestWithMethod:@"GET" url:getPrices.address parameters:requestDict success:^(id jsonObject) {
		GetPricesResponseJsonMapper *mapper = [[GetPricesResponseJsonMapper alloc] init];
		if (![mapper parseWithJSONObject:jsonObject]) {
			GetPricesResponse *response = mapper.response;
			PPLBasedPrice *price = [[PPLBasedPrice alloc] init];
			for (GetProductOptionsResponsePeopleType *peopleType in response.prices.firstObject.price) {
				if ([peopleType.name isEqualToString:@"child"]) {
					price.enable_child = YES;
				} else if ([peopleType.name isEqualToString:@"infant"]) {
					price.enable_infant = YES;
				} else if ([peopleType.name isEqualToString:@"senior"]) {
					price.enable_senior = YES;
				} else if ([peopleType.name isEqualToString:@"junior"]) {
					price.enable_junior = YES;
				} else if ([peopleType.name isEqualToString:@"student"]) {
					price.enable_student = YES;
				} else if ([peopleType.name isEqualToString:@"soldier"]) {
					price.enable_soldier = YES;
				}
			}
			self.entry.product.PPLBasedPrice = price;
			PPLBasedCountData *countData = [[PPLBasedCountData alloc] init];
			countData.adultCount = 1;
			self.entry.PPLBasedCountData = countData;

			[self buildCellDataSource];
			[self.tableView reloadData];
			[self performRequestForGetPersonPrices];
		}
	}];
}

#pragma mark - Segue

- (void)performRequestForGetPersonPrices {
	GetPersonPrices *getPersonPrices = [[GetPersonPrices alloc] init];
	getPersonPrices.pid = self.bookingReportDetail.pid;
	getPersonPrices.date = self.service_date;
	getPersonPrices.arrivalStopId = self.bookingReportDetail.arrivalScheduleStop.id;
	getPersonPrices.departureStopId = self.bookingReportDetail.departureScheduleStop.id;
	NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
	for (NSString *type in self.entry.product.PPLBasedPrice.allowedTypes) {
		dictionary[type] = @([SoldStock filteredStocks:self.entry.stocks byBasedType:type].count);
	}
	getPersonPrices.personData = [NSDictionary dictionaryWithDictionary:dictionary];

	NSDictionary *requestDict = [BeanUtils describe:getPersonPrices];

	[Utility performRESTRequestWithMethod:@"POST" url:getPersonPrices.address parameters:requestDict success:^(id jsonObject) {
		self.totalPrice = [[jsonObject valueForKeyPath:@"@sum.floatValue"] floatValue];
		[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:self.tableView.numberOfSections - 1]] withRowAnimation:UITableViewRowAnimationNone];
	}];
}

- (void)performRequestForBookBus {
	BookBus *bookbus = [[BookBus alloc] init];
	bookbus.ignoreDuplicated = YES;

	[self.entry.stocks bk_each:^(SoldStock *stock) {
		if ([StringUtils isEmpty:stock.sold_to_name]) {
			stock.sold_to_name = @"cash";
		}
	}];
	bookbus.travelerDetails = [WebService travelerDetailsWithCartEntries:@[self.entry]];

	Address *primaryAddress = [Address primaryOfAddresses:[Vars appDelegate].loginUser.contactInfos];
	if (primaryAddress) {
		Address *contactInfo = [primaryAddress copy];
		contactInfo.aid = 0;
		contactInfo.isDefault = NO;
		bookbus.contactInfo = contactInfo;
	} else {
		bookbus.contactInfo = [[Address alloc] initWithType:AddressTypeContactInfo];
	}

	_PaymentInfo *paymentInfo = [[_PaymentInfo alloc] init];
	paymentInfo.payment_type = 1;
	bookbus.paymentInfo = paymentInfo;

	bookbus.cashAmount = self.totalPrice;
	bookbus.cashSaleVendorId = [Vars appDelegate].loginUser.id;

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

	[Utility getXMLFromRequestWithMethod:@"POST" url:bookbus.address parameters:requestDict success:^(NSString *xml) {
		// NSLog(@"%@", xml);
		BookGoodsResponseJsonMapper *mapper = [[BookGoodsResponseJsonMapper alloc] init];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:xml objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			BookGoodsResponse *response = mapper.response;
			if (![StringUtils isEmpty:response.order_code]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:@"Book Bus Successfully!" dismissalHandler:^{
					[self.navigationController popViewControllerAnimated:YES];
				}];
			} else {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:[Vars responseException]];
			}
		}
	}];
}

#pragma mark - Segue

- (void)performSegueForCalendarOnTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
	CalendarViewController *viewController = [[CalendarViewController alloc] init];
	viewController.title = IMLocalizedString(@"Departure Date");
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.calendarManager.minimumDate = [NSDate date];
	viewController.calendarManager.maximumDate = [DateUtils addMonths:[NSDate date] amount:6];
	[viewController.calendarManager setDidSelectDateBlock:^(NSDate *date) {
		[self.navigationController popViewControllerAnimated:YES];
		self.service_date = [[DateFormatUtils ISO_DATE_FORMAT] format:date];
		[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
		[self performRequestForGetPersonPrices];
	}];
	if (![StringUtils isEmpty:self.service_date]) {
		[viewController selectDate:[[DateFormatUtils ISO_DATE_FORMAT] parse:self.service_date]];
	}
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Private
- (void)buildCellDataSource {
	@weakify(self)
	NSMutableArray *arrays = [NSMutableArray array];
	if (YES) {
		NSMutableArray *array = [NSMutableArray array];
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.style = UITableViewCellStyleSubtitle;
			data.textColor = [Vars defaultTintColor];
			data.detailText = IMLocalizedString(@"Departure Date");
			data.detailTextColor = [UIColor lightGrayColor];
			data.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
			data.accessoryDisclosureIndicatorColor = [UIColor lightGrayColor];
			[data setPreInstallBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				data.text = [Utility localizedStringWithStandardDateString:self.service_date];
			}];
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self performSegueForCalendarOnTableView: tableView atIndexPath:indexPath];
			}];
			[array addObject:data];
		}
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.style = UITableViewCellStyleSubtitle;
			data.text = self.bookingReportDetail.departureScheduleStop.departureOption;
			data.detailText = @"Departure";
			data.detailTextColor = [UIColor lightGrayColor];
			data.allowsTextLineWrapping = YES;
			[array addObject:data];
		}
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.style = UITableViewCellStyleSubtitle;
			data.text = self.bookingReportDetail.arrivalScheduleStop.arrivalOption;
			data.detailText = @"Arrival";
			data.detailTextColor = [UIColor lightGrayColor];
			data.allowsTextLineWrapping = YES;
			[array addObject:data];
		}
		[arrays addObject:[NSArray arrayWithArray:array]];
	}
	if (YES) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		[data setPreInstallBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
			@strongify(self)
			data.text = self.entry.shortDescription;;
		}];
		[arrays addObject:@[data]];
	}
	for (NSString *type in self.entry.product.PPLBasedPrice.allowedTypes) {
		NSMutableArray *array = [NSMutableArray array];
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.style = UITableViewCellStyleValue1;
			data.text = IMLocalizedString(type);
			data.textColor = [Vars defaultTintColor];
			data.stepValue = @1;
			data.minimumValue = [type isEqualToString:@"Adult"] ? @1 : @0;
			data.maximumValue = @50;
			data.editingType = TableViewCellEditingTypeStepper;
			[data setValueObservingGetterBlock:^id {
				@strongify(self)
				NSArray *stocks = [SoldStock filteredStocks:self.entry.stocks byBasedType:type];
				return @(stocks.count);
			}];
			[data setValueChangedPostActionBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data, IMStepper *stepper) {
				@strongify(self)
				[self changePassengerListByType: type toCount:(int)stepper.value onTableView: tableView atIndexPath: indexPath];
			}];
			[array addObject:data];
		}
		for (SoldStock *stock in [SoldStock filteredStocks:self.entry.stocks byBasedType:type]) {
			[array addObject:[self buildTableViewCellDataWithStock:stock]];
		}
		[arrays addObject:array];
	}
	if (YES) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.style = UITableViewCellStyleValue1;
		data.text = @"Cash collected $";
		data.editingType = TableViewCellEditingTypeTextField;
		data.keyboardType = UIKeyboardTypeDecimalPad;
		[data setValueObservingGetterBlock:^id {
			return [NSString stringWithFormat:@"%g", self.totalPrice];
		}];
		[data setValueObservingSetterBlock:^(id value) {
			self.totalPrice = [value floatValue];
		}];
		[arrays addObject:@[data]];
	}
	self.cellDataArrays = [NSArray arrayWithArray:arrays];
}

- (void)changePassengerListByType:(NSString *)type toCount:(NSInteger)count onTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)indexPath {
	NSInteger oldCount = [SoldStock filteredStocks:self.entry.stocks byBasedType:type].count;
	NSInteger newCount = count;
	if (oldCount != newCount) {
		NSInteger index = -1;
		for (NSString *PPLBasedType in self.entry.product.PPLBasedPrice.allowedTypes) {
			index += [SoldStock filteredStocks:self.entry.stocks byBasedType:PPLBasedType].count;
			if ([PPLBasedType isEqualToString:type]) {
				break;
			}
		}
		NSMutableArray *array = self.cellDataArrays[indexPath.section];
		NSMutableArray *indexPaths = [NSMutableArray array];
		if (oldCount < newCount) {
			for (int i = 0; i < newCount - oldCount; i++) {
				SoldStock *stock = [[SoldStock alloc] init];
				stock.people_type = type;
				[self.entry.stocks insertObject:stock atIndex:index + 1 + i];
				[indexPaths addObject:[NSIndexPath indexPathForRow:array.count inSection:indexPath.section]];
				[array addObject:[self buildTableViewCellDataWithStock:stock]];
			}
			[tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
		} else if (oldCount > newCount) {
			for (int i = 0; i < oldCount - newCount; i++) {
				[self.entry.stocks removeObjectAtIndex:index - i];
				[array removeLastObject];
				[indexPaths addObject:[NSIndexPath indexPathForRow:array.count inSection:indexPath.section]];
			}
			[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
		}
	} else {
		[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationNone];
	}
	[self performRequestForGetPersonPrices];
}

- (TableViewCellData *)buildTableViewCellDataWithStock:(SoldStock *)stock {
	NSMutableString *string = [NSMutableString string];
	[string im_appendString:IMLocalizedString(stock.people_type)];
	[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
	[string appendFormat:@"%d", [[SoldStock filteredStocks:self.entry.stocks byBasedType:stock.people_type] indexOfObject:stock] + 1];
	TableViewCellData *data = [[TableViewCellData alloc] init];
	data.style = UITableViewCellStyleValue2;
	data.text = [NSString stringWithString:string];
	data.editingType = TableViewCellEditingTypeTextField;
	data.autocapitalizationType = UITextAutocapitalizationTypeWords;
	data.textContentType = IMTextContentTypeName;
	data.placeholder = IMLocalizedString(@"Traveler Name");
	data.observedObject = stock;
	data.keyPath = @"sold_to_name";
	[data setKeyboardToolbarActionForSelectionOfContactWithDisplayedPropertyKeys:@[CMContactGivenNameKey, CMContactFamilyNameKey] completion:^id (CMContact *contact) {
		stock.sold_to_name = contact.fullName;
		return nil;
	}];
	[data addIntegrityValidationRuleBlock:^BOOL {
		return [Utility canBeConvertedToUrlEncodedFromString:stock.sold_to_name];
	} withMessageBlock:^NSString *{
		return IMLocalizedString(@"Please enter alphabetic characters only");
	}];
	return data;
}

- (BOOL)performValidationForBookBus {
	if (self.totalPrice <= 0) {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:[Vars responseException]];
		return NO;
	}
	[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)reloadFixedFooterView {
}

#pragma mark - Table view methods

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

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

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
	if (section == 1 || section == tableView.numberOfSections - 1) {
		return @" ";
	}
	return nil;
}

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArrays[indexPath.section][indexPath.row];
	return [UIToolkit tableView:tableView atIndexPath:indexPath cellWithData: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
