//
// TourSearchListViewController.m
// IvyMedia
//
// Created by haibara on 9/3/14.
//
//

#import "TourSearchListViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import "DrawUtils.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import "DZNEmptyDataSetDefault.h"
#import "MJRefreshLocalization.h"
#import <BlocksKit/BlocksKit.h>
#import <libextobjc/EXTScope.h>
#import <MJRefresh/MJRefresh.h>
#import <SDWebImage/UIImageView+WebCache.h>
#import <PureLayout/PureLayout.h>
#import "Utility.h"
#import "AppTracker.h"
#import "TourSearchData.h"
#import "SearchTourResponseJsonMapper.h"
#import "TourSearchListSmallCell.h"
#import "TourSearchDetailViewController.h"
#import "TourSearchFilterViewController.h"
#import "Vars.h"

@interface TourSearchListParam () <NSCopying>
@property (nonatomic, assign) BOOL hideComingSoonTour;
@end

@implementation TourSearchListParam

- (instancetype)init {
	self = [super init];
	if (self) {
		self.hideComingSoonTour = YES;
	}
	
	return self;
}

- (BOOL)isEqual:(id)object {
	if (self == object) {
		return YES;
	}
	if (![object isKindOfClass:self.class]) {
		return NO;
	}
    return [[BeanUtils describe:self] isEqualToDictionary:[BeanUtils describe:object]];
}

- (id)copyWithZone:(NSZone *)zone {
	return [BeanUtils copyWithZone:zone origin:self];
}

#pragma mark - Public

- (NSDictionary *)toParameters {
	NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[CocoaUtils nonEmptyDictionary:[BeanUtils describeAccessibleSimple:self]]];
	if (self.destinations.count > 0) {
		dict[@"destinations"] = [self.destinations componentsJoinedByString:@";"];
	}
	if (self.departures.count > 0) {
		dict[@"departures"] = [self.departures componentsJoinedByString:@";"];
	}
	if (self.duration.count > 0) {
		if (self.duration.count > 1) {
		self.duration =  [self.duration bk_map:^id _Nonnull(NSString *day) {
				if ([day containsString:@"-"]) {
				return 	[day stringByReplacingOccurrencesOfString:@"-" withString:@""];
				}
				return day;
			}];
		}
		dict[@"duration"] = [self.duration componentsJoinedByString:@";"];
	}
	if (self.startDates.count > 0) {
		dict[@"startDates"] = [self.startDates componentsJoinedByString:@";"];
	}
	if (self.promotionType.count > 0) {
		dict[@"promotionType"] = [self.promotionType componentsJoinedByString:@";"];
	}
	return [NSDictionary dictionaryWithDictionary:dict];
}

@end

@interface TourSearchPaginationParam () <NSCopying>
@property (nonatomic, assign) BOOL returnUnicode;
@end

@implementation TourSearchPaginationParam

- (instancetype)init {
	self = [super init];
	if (self) {
		self.pageLength = 20;
		self.returnUnicode = @YES;
	}
	return self;
}

- (id)copyWithZone:(NSZone *)zone {
	return [BeanUtils copyWithZone:zone origin:self superClass:self.superclass];
}

#pragma mark - Public

- (NSDictionary *)toParameters {
	NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[CocoaUtils nonEmptyDictionary:[BeanUtils describeAccessibleSimple:self superClass:self.superclass]]];
	[dict addEntriesFromDictionary:[super toParameters]];
	return [NSDictionary dictionaryWithDictionary:dict];
}

@end

@interface TourSearchListViewController () <DZNEmptyDataSetDefault, DZNEmptyDataSetDelegate>
@property (nonatomic, strong) NSMutableArray *tourSeachResults;
@property (nonatomic, strong) NSDictionary *tourFilterDict;
@property (nonatomic, strong) NSMutableArray *cellDataArray;
@end

@implementation TourSearchListViewController

- (instancetype)init {
	self = [super init];
	if (self) {
		// Custom initialization
		// self.extendedLayoutIncludesOpaqueBars = YES;
		self.title = IMLocalizedString(@"Loading...");
		[[Vars appDelegate] applyDefaultConfigurationForViewController:self];
	}
	return self;
}

- (void)viewDidLoad {
	[super viewDidLoad];
	[[AppTracker sharedInstance] sendView:[self class]];
	
	self.tourSeachResults = [NSMutableArray array];
	self.cellDataArray = [NSMutableArray array];
	// Do any additional setup after loading the view from its nib.
	self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[DrawUtils imageWithFAKIcon:[FAKFontAwesome filterIconWithSize:24] fillColor:[UIColor blackColor]] style:UIBarButtonItemStylePlain target:self action:@selector(filterSearchResult)];
	self.navigationItem.rightBarButtonItem.enabled = NO;

	self.tableView.emptyDataSetDelegate = self;
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([TourSearchListSmallCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([TourSearchListSmallCell class])];

	@weakify(self)
	MJRefreshNormalHeader * refreshHeader = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
		@strongify(self)
		[self clearTourSearchResults];
		[self searchTour:YES];
	}];
	refreshHeader.automaticallyChangeAlpha = YES;
	refreshHeader.lastUpdatedTimeLabel.hidden = YES;
	self.tableView.mj_header = refreshHeader;
	MJRefreshBackNormalFooter *refreshFooter = [MJRefreshBackNormalFooter footerWithRefreshingBlock:^{
		@strongify(self)
		[self searchTour: YES];
	}];
	refreshFooter.automaticallyChangeAlpha = YES;
	self.tableView.mj_footer = refreshFooter;
}

- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	// ajax
	if (self.tourSearchParam.pageNumber == 0) {
		[self searchTour:NO];
	}
}

#pragma mark - Public

- (void)clearTourSearchResults {
	self.tourSearchParam.pageNumber = 0;
}

#pragma mark - Action

- (void)filterSearchResult {
	TourSearchFilterViewController *viewController = [[TourSearchFilterViewController alloc] init];
	viewController.tourFilterDict = self.tourFilterDict;
	viewController.tourSearchParam = self.tourSearchParam;
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)showDetailWithObject:(TourSearchData *)object {
	TourSearchDetailViewController *viewController = [[TourSearchDetailViewController alloc] init];
	viewController.tourSearchData = object;
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Network

- (void)searchTour:(BOOL)circle {
	BOOL initial = self.tourSearchParam.pageNumber == 0;
	self.tourSearchParam.pageNumber++;
	__block NSInteger total = 0;

	SearchTour *searchTour = [[SearchTour alloc] init];
	NSMutableDictionary *requrestDict = [self.tourSearchParam toParameters];

	[Utility performSOAPRequestWithUrl:searchTour.address namespace:searchTour.namespace name:searchTour.name parameters:requrestDict beforeSend:^{
		if (!circle) {
			[CocoaUtils showBusyIndicator:self.view];
			self.tableView.mj_header.hidden = YES;
			self.tableView.mj_footer.hidden = YES;
		}
		self.tableView.emptyDataSetSource = nil;
		self.tableView.emptyDataSetDelegate = nil;
	} success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		if (initial) {
			[self.tourSeachResults removeAllObjects];
			[self.cellDataArray removeAllObjects];
			self.tourFilterDict = nil;
		}
		NSString *ret = [CocoaUtils firstValueMatchedInString:responseStr forElement:@"return"];
		if (ret) {
			NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:[ret dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL];
			if (jsonArray.count > 0) {
				NSDictionary *root = jsonArray.firstObject;
				total = [root[@"total"] intValue];
				NSString *resultXml = root[@"resultXml"];
				if (![StringUtils isEmpty:resultXml]) {
					// resultXml = [resultXml stringByReplacingOccurrencesOfString:@"\n" withString:@""];
				}
				resultXml = [CocoaUtils noDeclarationXmlString:resultXml];
				// NSLog(@"%@", resultXml);
				SearchTourResponseJsonMapper *mapper = [[SearchTourResponseJsonMapper alloc] init];
				NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:resultXml objectMapping:mapper.objectMapping];
				if (![mapper parseWithJSONObject:jsonDict]) {
					SearchTourResponse *response = mapper.response;
					[self.tourSeachResults addObjectsFromArray:response.products];
					[self updateTableViewCellDataArrayByTourSearchDataList:response.products];
				}
				NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithDictionary:root];
				[dictionary removeObjectForKey:@"resultXml"];
				self.tourFilterDict = [NSDictionary dictionaryWithDictionary:dictionary];
				// NSLog(@"%@", self.tourFilterDict);
			}
		}
		if (initial) {
			[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
		}
		self.title = total > 0 ? [NSString stringWithFormat:total > 1 ? IMLocalizedString(@"Showing %d Tours") : IMLocalizedString(@"Showing %d Tour"), total] : IMLocalizedString(@"No Search Results");
		self.navigationItem.rightBarButtonItem.enabled = self.tourFilterDict ? YES : NO;
	} complete:^{
		if (!circle) {
			if (self.tourSeachResults.count >= total) {
				[self.tableView.mj_footer endRefreshingWithNoMoreData];
				self.tableView.mj_footer.hidden = YES;
			} else {
				[self.tableView.mj_footer resetNoMoreData];
				self.tableView.mj_footer.hidden = NO;
			}
		} else {
			[self.tableView.mj_header endRefreshing];
			if (self.tourSeachResults.count >= total) {
				[self.tableView.mj_footer endRefreshingWithNoMoreData];
				self.tableView.mj_footer.hidden = YES;
			} else {
				[self.tableView.mj_footer endRefreshing];
				self.tableView.mj_footer.hidden = NO;
			}
		}
		if (!circle) {
			self.tableView.mj_header.hidden = NO;
			[CocoaUtils hideBusyIndicator:self.view];
		}
		self.tableView.emptyDataSetSource = self;
		self.tableView.emptyDataSetDelegate = self;
		[self.tableView reloadData];
	}];
}

#pragma mark - Private

- (void)updateTableViewCellDataArrayByTourSearchDataList:(NSArray *)objects {
	@weakify(self)
	NSMutableArray *tempArray = [NSMutableArray array];
	for (TourSearchData *obj in objects) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.reuseIdentifier = NSStringFromClass([TourSearchListSmallCell class]);
		data.weaklyAssociatedObject = obj;
		[data setNeedLayoutFittingHeight];
		[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
			@strongify(self)
			[self showDetailWithObject: obj];
		}];
		[tempArray addObject:data];
	}
	[self.cellDataArray addObjectsFromArray:tempArray];
}

#pragma mark - Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return 1;
}

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

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArray[indexPath.row];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([TourSearchListSmallCell class])]) {
		return [UIToolkit instantiateRowHeightForTableViewCellWithNibName:NSStringFromClass([TourSearchListSmallCell class])];
	}
	return [UIConstants defaultTableViewRowHeight];
}

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArray[indexPath.row];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([TourSearchListSmallCell class])]) {
		TourSearchListSmallCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([TourSearchListSmallCell class])];
		TourSearchData *object = data.weaklyAssociatedObject;
		cell.productNameLabel.text = object.product_name;
		NSString *imageUrl = [object adaptiveImageUrlByWidth:CGRectGetWidth(cell.logoImageView.frame)];
		if (imageUrl) {
			[cell.logoImageView sd_setImageWithURL:[NSURL URLWithString:imageUrl]];
		}
		cell.tourOfLabel.hidden = !object.is_today_deal;
		cell.reViewsLabel.attributedText = [object attributedReviewTextWithFont:cell.reViewsLabel.font highlighted:NO];
		if (YES) {
			NSMutableString *string = [NSMutableString string];
			[string im_appendString:IMLocalizedString(@"Tour Code")];
			[string im_appendString:IMLocalizedString(PUNCTUATION_COLON)];
			[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
			[string im_appendString:object.tour_code];
			cell.tourCodeLabel.text = string;
		}
		cell.priceLabel.attributedText = [object attributedPriceTextWithFont:[UIFont preferredFontForTextStyle:UIFontTextStyleCaption2]];
		cell.describeLabel.text = object.promotionText;
		return cell;
	}
	return [UIToolkit tableView:tableView atIndexPath:indexPath cellWithData:data];
}

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

#pragma mark - DZNEmptyDataSetDelegate

- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView {
	return YES;
}

@end
