//
// TourSearchDetailsViewController.m
// IvyMedia
//
// Created by paul on 9/10/14.
//
//

#import "TourSearchDetailViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "CocoaUtils.h"
#import "DrawUtils.h"
#import "ImageUtils.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import "DTAttributedTextViewController.h"
#import <BlocksKit/A2DynamicDelegate.h>
#import <BlocksKit/NSObject+A2DynamicDelegate.h>
#import <libextobjc/EXTScope.h>
#import <PureLayout/PureLayout.h>
#import <SDWebImage/SDWebImageManager.h>
#import <XMLDictionary/XMLDictionary.h>
#import "Utility.h"
#import "AppTracker.h"
#import "CartEntry.h"
#import "Label.h"
#import "PerlWS.h"
#import "GetTourDetailsResponseJsonMapper.h"
#import "TourSearchDetailRichFoldingCell.h"
#import "TourSearchDetailSummaryCell.h"
#import "TourSearchDetailTopCell.h"
#import "LoginViewController.h"
#import "TourSearchBusStopListViewController.h"
#import "TourSearchOptionViewController.h"
#import "TourSearchParkingListViewController.h"
#import "TourSearchReviewListViewController.h"
#import "TourSearchSubDetailVC.h"
#import "DiscountTipTool.h"
#import "Vars.h"


@interface TourSearchDetailViewController ()

@property (nonatomic, strong) UIButton *bookButton;

@property (nonatomic, strong) NSArray *cellDataArrays;
@property (nonatomic, strong) GetTourDetailsResponseData *tour_detail;

@end

@implementation TourSearchDetailViewController

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

- (void)viewDidLoad {
	[super viewDidLoad];

	[[AppTracker sharedInstance] sendView:[self class]];
	
	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 setTitle:IMLocalizedString(@"Book Now") forState:UIControlStateNormal];
		[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		[button addTarget:self action:@selector(bookNow) forControlEvents:UIControlEventTouchUpInside];
		[Utility addInsetToFooterViewIfSafeArea:button];
		self.fixedFooterView = button;
	}

	self.tableView.sectionHeaderHeight = [UIConstants defaultTableViewCellLayoutInsets].top;
	self.tableView.sectionFooterHeight = [UIConstants defaultTableViewCellLayoutInsets].bottom;
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([TourSearchDetailTopCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([TourSearchDetailTopCell class])];
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([TourSearchDetailRichFoldingCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([TourSearchDetailRichFoldingCell class])];
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([TourSearchDetailSummaryCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([TourSearchDetailSummaryCell class])];
	[self buildCellDataSource];
	[self reloadHeaderFooter];
}

- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	// ajax
	if (!self.tourSearchData || !self.tour_detail) {
		[self getTourDetails];
	}
}

#pragma mark - Public

- (NSString *)tourCode {
	if (_tourCode) {
		return _tourCode;
	} else if (self.tourSearchData) {
		return self.tourSearchData.tour_code;
	}
	return nil;
}

#pragma mark - Action

- (void)bookNow {
	Label *label = [[Label alloc] init];
	label.alias = @"date";
	label.name = IMLocalizedString(@"Departure Date");
	label.options = self.tourSearchData.date_options;

	CartEntry *entry = [[CartEntry alloc] init];
	entry.product.product_id = self.tourSearchData.pid;
	entry.product.p_type = 2;
	entry.product.tour_code = self.tourSearchData.tour_code;
	entry.product.name = self.tourSearchData.product_name;
	entry.product.labels = @[label];
	entry.product.termsConditions = self.tour_detail.terms_and_condition;
	if ([StringUtils isEmpty:self.tour_detail.departs_from]) {
		entry.product.piwikCategory = @"Tour";
	} else if ([self.tour_detail.departs_from containsString:@";"]) {
		NSArray *array = [self.tour_detail.departs_from componentsSeparatedByString:@";"];
		entry.product.piwikCategory = array[0];
	} else {
		entry.product.piwikCategory = self.tour_detail.departs_from;
	}
	
	TourSearchOptionViewController *viewController = [[TourSearchOptionViewController alloc] init];
	viewController.entry = entry;
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Segue

- (void)performSegueForHTMLString:(NSString *)HTMLString andTitle:(NSString *)title isListStyle:(BOOL)isListStyle {
	DTAttributedTextViewController *viewController = [[DTAttributedTextViewController alloc] init];
	viewController.title = title;
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.textView.attributedTextContentView.edgeInsets = isListStyle ? UIEdgeInsetsMake(5, 5, 15, 15) : UIEdgeInsetsMake(15, 20, 5, 15);
	viewController.textView.attributedString = [[NSAttributedString alloc] initWithHTMLData:[HTMLString dataUsingEncoding:NSUTF8StringEncoding] options:[self optionsForDisplayingHTMLString] documentAttributes:NULL];
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForReviewList {
	TourSearchReviewListViewController *viewController = [[TourSearchReviewListViewController alloc] init];
	viewController.reviewTotal = self.tourSearchData.review_total;
	viewController.tourCode = self.tourSearchData.tour_code;
	viewController.isOneDay = self.tourSearchData.days == 1;
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Network

- (void)getTourDetails {
	GetTourDetails *getTourDetails = [[GetTourDetails alloc] init];
	getTourDetails.tourCode = self.tourCode;
	getTourDetails.appendSearchData = !self.tourSearchData;

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

	[Utility getXMLFromRequestWithMethod:@"GET" url:getTourDetails.address parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		GetTourDetailsResponseJsonMapper *mapper = [[GetTourDetailsResponseJsonMapper alloc] init];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			GetTourDetailsResponse *response = mapper.response;
			if (response.error_code > 0) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error_message];
			} else {
				if (!self.tourSearchData) {
					self.tourSearchData = response.product;
				}
				self.tour_detail = response.details;
				[self buildCellDataSource];
				[self.tableView reloadData];
				[self reloadHeaderFooter];
			}
		}
	}];
}

#pragma mark - Private

- (void)buildCellDataSource {
	NSMutableArray *arrays = [NSMutableArray array];
	if (self.tourSearchData) {
		TableViewCellData *data = [[TableViewCellData alloc] init];
		data.reuseIdentifier = NSStringFromClass([TourSearchDetailTopCell class]);
		[data setNeedLayoutFittingHeight];
		[arrays addObject:@[data]];
	}
	if (self.tour_detail) {
		if (self.tour_detail.highlights) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.reuseIdentifier = NSStringFromClass([TourSearchDetailRichFoldingCell class]);
			data.identifier = @"highlights";
			data.weaklyAssociatedObject = self.tour_detail.highlights;
			data.stronglyAssociatedObject = @NO;
			[data setNeedLayoutFittingHeight];
			[data setVaryingHeightIdentifierBlock:^NSString *(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data){
				return [NSString stringWithFormat:@"%@", data.stronglyAssociatedObject];
			}];
			[arrays addObject:@[data]];
		}
		if (self.tour_detail.special_remarks) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.reuseIdentifier = NSStringFromClass([TourSearchDetailRichFoldingCell class]);
			data.identifier = @"special_remarks";
			data.weaklyAssociatedObject = self.tour_detail.special_remarks;
			data.stronglyAssociatedObject = @NO;
			[data setNeedLayoutFittingHeight];
			[data setVaryingHeightIdentifierBlock:^NSString *(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data){
				return [NSString stringWithFormat:@"%@", data.stronglyAssociatedObject];
			}];
			[arrays addObject:@[data]];
		}
		if (self.tour_detail.lowest_price) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.reuseIdentifier = NSStringFromClass([TourSearchDetailSummaryCell class]);
			data.identifier = @"lowest_price";
			data.weaklyAssociatedObject = self.tour_detail.lowest_price;
			[arrays addObject:@[data]];
		}
		if (self.tour_detail.pricing_policy) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.reuseIdentifier = NSStringFromClass([TourSearchDetailRichFoldingCell class]);
			data.identifier = @"pricing_policy";
			data.weaklyAssociatedObject = self.tour_detail.pricing_policy;
			data.stronglyAssociatedObject = @NO;
			[data setNeedLayoutFittingHeight];
			[data setVaryingHeightIdentifierBlock:^NSString *(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data){
				return [NSString stringWithFormat:@"%@", data.stronglyAssociatedObject];
			}];
			[arrays addObject:@[data]];
		}
		if (YES) {
			NSMutableArray *array = [NSMutableArray array];
			@weakify(self)
			if (YES) {
				NSMutableArray *dailyTrips = [NSMutableArray array];
				if (self.tour_detail.dates.count > 0) {
					NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"^%@ ", [IMLocalizedString(@"Day %d") stringByReplacingOccurrencesOfString:@"%d" withString:@"(\\d+)"]] options:NSRegularExpressionCaseInsensitive error:NULL];
					for (GetTourDetailsResponseDailyTrip *date in self.tour_detail.dates) {
						if (date.title && date.content) {
							NSString *title = [CocoaUtils stripHtmlString:date.title];
							NSTextCheckingResult *match = [regex firstMatchInString:title options:0 range:NSMakeRange(0, title.length)];
							if (match && match.numberOfRanges > 1) {
								GetTourDetailsResponseDailyTrip *dailyTrip = [[GetTourDetailsResponseDailyTrip alloc] init];
								NSInteger nth_day = [[title substringWithRange:[match rangeAtIndex:1]] intValue];
								dailyTrip.nth_day = nth_day;
								dailyTrip.title = [title substringFromIndex:[match rangeAtIndex:0].length];
								dailyTrip.content = date.content;
								[dailyTrips addObject:dailyTrip];
							}
						}
					}
				}
				if (dailyTrips.count > 0 || self.tour_detail.dc_description || self.tour_detail.bottom_dc_description) {
					TableViewCellData *data = [[TableViewCellData alloc] init];
					FAKIcon *icon = [FAKFontAwesome universityIconWithSize:10];
					icon.drawingPositionAdjustment = UIOffsetMake(0, -1);
					data.image = [self getTableViewCellImageWithForegroundIcon:icon];
					data.text = IMLocalizedString(@"Itinerary Details");
					data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
					data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
					[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
						@strongify(self)
						TourSearchSubDetailVC *viewController = [[TourSearchSubDetailVC alloc] init];
						viewController.dailyTrips = [NSArray arrayWithArray:dailyTrips];
						viewController.topDescription = self.tour_detail.dc_description;
						viewController.bottomDescription = self.tour_detail.bottom_dc_description;
						[self.navigationController pushViewController:viewController animated:YES];
					}];
					[array addObject:data];
				}
			}
			if (self.tour_detail.bus_stops.count > 0) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.text = IMLocalizedString(@"Departure & Return");
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome exchangeIconWithSize:12]];
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					TourSearchBusStopListViewController *viewController = [[TourSearchBusStopListViewController alloc] init];
					viewController.busStops = self.tour_detail.bus_stops;
					viewController.stopNote = self.tour_detail.stop_note;
					[self.navigationController pushViewController:viewController animated:YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.parking_stops.count > 0) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome carIconWithSize:12]];
				data.text = IMLocalizedString(@"Parking Information");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					TourSearchParkingListViewController *viewController = [[TourSearchParkingListViewController alloc] init];
					viewController.parkings = self.tour_detail.parking_stops;
					[self.navigationController pushViewController:viewController animated:YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.inclusion) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome checkIconWithSize:14]];
				data.text = IMLocalizedString(@"Inclusion");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForHTMLString: self.tour_detail.inclusion andTitle:IMLocalizedString(@"Inclusion") isListStyle: YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.exclusion) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome timesIconWithSize:14]];
				data.text = IMLocalizedString(@"Exclusion");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForHTMLString: self.tour_detail.exclusion andTitle:IMLocalizedString(@"Exclusion") isListStyle: YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.additional_note) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome exclamationIconWithSize:14]];
				data.text = IMLocalizedString(@"Additional Note");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForHTMLString: self.tour_detail.additional_note andTitle:IMLocalizedString(@"Additional Note") isListStyle: YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.confirmation) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome starIconWithSize:14]];
				data.text = IMLocalizedString(@"Confirmation");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForHTMLString: self.tour_detail.confirmation andTitle:IMLocalizedString(@"Confirmation") isListStyle: YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.redemption) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome dollarIconWithSize:12]];
				data.text = IMLocalizedString(@"Redemption");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForHTMLString: self.tour_detail.redemption andTitle:IMLocalizedString(@"Redemption") isListStyle: YES];
				}];
				[array addObject:data];
			}
			if (self.tour_detail.terms_and_condition) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				data.image = [self getTableViewCellImageWithForegroundIcon:[FAKFontAwesome listIconWithSize:12]];
				data.text = IMLocalizedString(@"Terms and Conditions");
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForHTMLString: self.tour_detail.terms_and_condition andTitle:IMLocalizedString(@"Terms and Conditions") isListStyle: NO];
				}];
				[array addObject:data];
			}
			if (YES) {
				TableViewCellData *data = [[TableViewCellData alloc] init];
				FAKIcon *icon = [FAKFontAwesome commentingIconWithSize:12];
				icon.drawingPositionAdjustment = UIOffsetMake(0, -2);
				data.image = [self getTableViewCellImageWithForegroundIcon:icon];
				if (self.tourSearchData.review_total > 0) {
					NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] im_initWithString:IMLocalizedString(@"Traveler Reviews")];
					NSMutableString *string = [NSMutableString string];
					[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
					[string im_appendString:IMLocalizedString(PUNCTUATION_PARENTHESES_LEFT)];
					[string appendFormat:@"%d", self.tourSearchData.review_total];
					[string im_appendString:IMLocalizedString(PUNCTUATION_PARENTHESES_RIGHT)];
					[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:string attributes:@{ NSForegroundColorAttributeName : [Vars defaultTintColor] }]];
					data.attributedText = [[NSAttributedString alloc] initWithAttributedString:attributedString];
				} else {
					data.text = IMLocalizedString(@"Traveler Reviews");
				}
				data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
				data.accessoryDisclosureIndicatorColor = [Vars defaultTintColor];
				[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
					@strongify(self)
					[self performSegueForReviewList];
				}];

				[array addObject:data];
			}
			[arrays addObject:[NSArray arrayWithArray:array]];
		}
	}
	self.cellDataArrays = [NSArray arrayWithArray:arrays];
}

- (UIImage *)getTableViewCellImageWithForegroundIcon:(FAKIcon *)icon {
	NSArray *icons = @[[FAKFontAwesome squareOIconWithSize:24], icon];
	UIImage *image = [UIImage imageWithStackedIcons:icons imageSize:CGSizeMake(24, 24)];
	return [ImageUtils adjustImage:image tintColor:[UIColor lightGrayColor]];
}

- (void)reloadHeaderFooter {
	self.tableView.tableHeaderView = nil;
	NSString *imageUrl = [self.tourSearchData adaptiveImageUrlByWidth:CGRectGetWidth([UIScreen mainScreen].bounds)];
	if (imageUrl) {
		[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:imageUrl] options:0 progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
			if (finished) {
				UIImage *scaleImage = [ImageUtils scaleImage:image byFactor:CGRectGetWidth([UIScreen mainScreen].bounds) / image.size.width];
				UIImage *cropImage = [ImageUtils cropImage:scaleImage toSize:CGSizeMake(scaleImage.size.width, MIN(ceil(CGRectGetHeight([UIScreen mainScreen].bounds) / 3), scaleImage.size.height))];
				UIImageView *topImageView = [[UIImageView alloc] initWithImage:cropImage];
                if (self.tourSearchData.is_today_deal) {
                    [topImageView addSubview:[DiscountTipTool labelForDealsWithText:IMLocalizedString(@"Tour of the Day") font:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]]];
					topImageView.clipsToBounds = YES;
                }
                self.tableView.tableHeaderView = topImageView;
			}
		}];
	}
	UIButton *bookButton = self.fixedFooterView;
	bookButton.hidden = !self.tourSearchData;
}

- (NSString *)HTMLStringWithContent:(NSString *)content prependingTitle:(NSString *)title {
	NSMutableString *string = [NSMutableString string];
	if (title) {
		[string im_appendString:@"<p><b>"];
		[string im_appendString:title];
		[string im_appendString:@"</b></p>"];
	}
	if (content) {
		[string im_appendString:content];
	}
	return [NSString stringWithString:string];
}

- (NSString *)wrapCSSAroundHTMLString:(NSString *)string {
	UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
	return [NSString stringWithFormat:@"<html><head><meta name=\"viewport\" content=\"width=device-width\"><style type=\"text/css\">"
									  @"body,table{font-family:\"%@\";font-size:%fpx;}"
									  @"body{margin:0;}"
									  @"table{width:auto!important;line-height:normal!important;}"
									  @"</style></head><body>%@</body></html>", font.familyName, font.pointSize, string];
}

- (NSDictionary *)optionsForDisplayingHTMLString {
	UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
	return @{ DTUseiOS6Attributes : @YES, DTDefaultFontFamily : font.familyName, DTDefaultFontSize : @(font.pointSize), DTDefaultLinkDecoration : @NO };
}

- (void)changeAccordionActive:(BOOL)active onTableView:(UITableView *)tableView atIndexPath:(NSIndexPath *)newIndexPath {
	NSMutableArray *indexPaths = [NSMutableArray array];
	for (int section = 0; section < self.cellDataArrays.count; section++) {
		for (int row = 0; row < [self.cellDataArrays[section] count]; row++) {
			TableViewCellData *data = self.cellDataArrays[section][row];
			NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
			if ([data.reuseIdentifier isEqualToString:NSStringFromClass([TourSearchDetailRichFoldingCell class])]) {
				if ([indexPath isEqual:newIndexPath]) {
					data.stronglyAssociatedObject = @(active);
					[indexPaths addObject:newIndexPath];
				} else if (active) {
					if ([data.stronglyAssociatedObject boolValue]) {
						data.stronglyAssociatedObject = @NO;
						if ([tableView.indexPathsForVisibleRows containsObject:indexPath]) {
							[indexPaths addObject:indexPath];
						}
					}
				}

			}
		}
	}
	[tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}

#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];
}

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

- (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];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([TourSearchDetailTopCell class])]) {
		TourSearchDetailTopCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([TourSearchDetailTopCell class])];
        cell.productNameLabel.text = self.tourSearchData.product_name;
        if (YES) {
            if (self.tourSearchData.promotions.count > 0) {
                NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]init];
				[self.tourSearchData.promotions enumerateObjectsUsingBlock:^(NSString *promotion, NSUInteger idx, BOOL * _Nonnull stop) {
					if (idx > 0) {
						if (idx % 2 == 0){
							[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\n" attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:5] }]];
						} else {
							[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"    " attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:5] }]];
						}
					}
					[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:[NSString stringWithFormat:@" %@ ", promotion] attributes:@{ NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1], NSBackgroundColorAttributeName : [CocoaUtils colorWithRGBs:StandardColorOrange], NSForegroundColorAttributeName : [UIColor whiteColor] }]];
				}];
                cell.saleMarkLabel.attributedText = attributedString;
            }
            else {
               cell.saleMarkLabel.text = nil;
            }
        }
		if (YES) {
			[cell.reviewButton removeTarget:self action:@selector(performSegueForReviewList) forControlEvents:UIControlEventTouchUpInside];
			[cell.reviewButton addTarget:self action:@selector(performSegueForReviewList) forControlEvents:UIControlEventTouchUpInside];
			NSAttributedString *reviewAttributedStr = [self.tourSearchData attributedReviewTextWithFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote] highlighted:YES];
			[cell.reviewButton setAttributedTitle:reviewAttributedStr forState:UIControlStateNormal];
		}
		if (YES) {
			NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
			if (YES) {
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Tour Code") attributes:@{ NSForegroundColorAttributeName : [UIColor darkGrayColor] }]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.tourSearchData.tour_code]];
			}
			if (![StringUtils isEmpty:self.tourSearchData.operates_on]) {
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Available") attributes:@{ NSForegroundColorAttributeName : [UIColor darkGrayColor] }]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.tourSearchData.operates_on]];
			}
			if (![StringUtils isEmpty:self.tourSearchData.departs_from]) {
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Depart From") attributes:@{ NSForegroundColorAttributeName : [UIColor darkGrayColor] }]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.tourSearchData.departs_from]];
			}
			if (![StringUtils isEmpty:self.tourSearchData.duration]) {
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Duration") attributes:@{ NSForegroundColorAttributeName : [UIColor darkGrayColor] }]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
				[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.tourSearchData.duration]];
			}
			cell.descLabel.attributedText = [[NSAttributedString alloc] initWithAttributedString:attributedString];
		}
		cell.priceLabel.attributedText = [self.tourSearchData attributedPriceTextWithFont:cell.descLabel.font];
		[cell setNeedsUpdateConstraints];
		return cell;
	} else if ([data.reuseIdentifier isEqualToString:NSStringFromClass([TourSearchDetailRichFoldingCell class])]) {
		TourSearchDetailRichFoldingCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([TourSearchDetailRichFoldingCell class])];
		if ([data.identifier isEqualToString:@"highlights"]) {
			cell.titleLabel.text = IMLocalizedString(@"Highlights");
		} else if ([data.identifier isEqualToString:@"special_remarks"]) {
			cell.titleLabel.text = IMLocalizedString(@"Special Remarks");
			cell.additionalPaddingAtBottom = 10;
		} else if ([data.identifier isEqualToString:@"pricing_policy"]) {
			cell.titleLabel.text = IMLocalizedString(@"Pricing Policies");
			cell.additionalPaddingAtBottom = 10;
		}
		cell.titleLabel.font = [CocoaUtils renderedFont:[UIFont preferredFontForTextStyle:UIFontTextStyleCaption1] withSymbolicTraits:UIFontDescriptorTraitBold];
		[cell setHTMLString:data.weaklyAssociatedObject options:[self optionsForDisplayingHTMLString]];
		cell.folding = [data.stronglyAssociatedObject boolValue];
		[cell ready];
		@weakify(self, tableView)
		[cell setToggleHandler:^(BOOL folding) {
			@strongify(self, tableView)
			[self changeAccordionActive: folding onTableView: tableView atIndexPath: indexPath];
		}];
		return cell;
	} else if ([data.reuseIdentifier isEqualToString:NSStringFromClass([TourSearchDetailSummaryCell class])]) {
		TourSearchDetailSummaryCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([TourSearchDetailSummaryCell class])];
		NSString *title = nil;
		if ([data.identifier isEqualToString:@"lowest_price"]) {
			title = IMLocalizedString(@"Pricing Details");
			cell.additionalPaddingAtBottom = 5;
		}
		@weakify(self, tableView)
		[cell setHTMLString:[self wrapCSSAroundHTMLString:[self HTMLStringWithContent:data.weaklyAssociatedObject prependingTitle:title]] didFinishLoad:^(CGSize contentSize) {
			@strongify(self, tableView)
			// WKWebView async evaluate javascript may dealloc crash
			if (tableView != self.tableView) {
				return;
			}
			CGFloat rowHeight = contentSize.height + [UIConstants defaultTableViewSeparatorHeight] / [UIScreen mainScreen].scale;
			if (data.reuseHeight != rowHeight) {
				data.reuseHeight = rowHeight;
				[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
			}
		}];
		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.cellDataArrays[indexPath.section][indexPath.row];
	[UIToolkit tableView:tableView atIndexPath:indexPath didSelectWithData:data];
}

@end
