//
// HotelSearchDetailsViewController.m
// Project
//
// Created by Ziv on 15/12/18.
//
//

#import "HotelSearchDetailViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import "DrawUtils.h"
#import "ImageUtils.h"
#import "RandomUtils.h"
#import "MapViewController.h"
#import "TextViewController.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import <BlocksKit/BlocksKit.h>
#import <BlocksKit/BlocksKit+UIKit.h>
#import <libextobjc/EXTScope.h>
#import <MWPhotoBrowser/MWPhotoBrowser.h>
#import <PureLayout/PureLayout.h>
#import <SDWebImage/UIImageView+WebCache.h>
#import "Utility.h"
#import "AppTracker.h"
#import "SalesEntryRoom.h"
#import "HotelWS.h"
#import "DiscountTipTool.h"
#import "HotelSearchDetailTopCell.h"
#import "BookingReviewViewController.h"
#import "Vars.h"

@interface HotelSearchDetailViewController () <MWPhotoBrowserDelegate>

@property (nonatomic, strong) NSArray *cellDataArrays;
@property (nonatomic, strong) NSArray *photos;
@property (nonatomic, strong) NSMutableDictionary *hotelPolicies;

@property (nonatomic, strong, readonly) NSAttributedString *fearutesAttributedString;
@property (nonatomic, strong, readonly) NSString *hotelCheckInOutText;

@end

@implementation HotelSearchDetailViewController

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

- (void)viewDidLoad {
	[super viewDidLoad];

	[[AppTracker sharedInstance] sendView:[self class]];
	
	self.hotelPolicies = [NSMutableDictionary dictionary];

	[self fetchPhotos];

	if ([Utility isValidPhoneNumber:self.hotelSearchData.hotel_description_ext.hotel_base_info.hotelPhone]) {
		@weakify(self)
		self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] im_initWithImage:[DrawUtils imageWithFAKIcon:[FAKFontAwesome phoneIconWithSize:24] fillColor:[UIColor blackColor]] style:UIBarButtonItemStylePlain handler:^(UIBarButtonItem *barButtonItem) {
			@strongify(self)
			[Utility callPhoneNumber: self.hotelSearchData.hotel_description_ext.hotel_base_info.hotelPhone];
		}];
	}

	self.tableView.sectionHeaderHeight = [UIConstants defaultTableViewCellLayoutInsets].top;
	self.tableView.sectionFooterHeight = [UIConstants defaultTableViewCellLayoutInsets].bottom;
	[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([HotelSearchDetailTopCell class]) bundle:nil] forCellReuseIdentifier:NSStringFromClass([HotelSearchDetailTopCell class])];
	[self reloadHeader];
	[self buildCellDataSource];
}

- (void)viewDidAppear:(BOOL)animated {
	[super viewDidAppear:animated];
	
	NSMutableArray *hotelEntries = [NSMutableArray array];
	NSMutableArray *otherEntries = [NSMutableArray array];
	for (CartEntry *entry in [Vars appDelegate].shopCarts.entries) {
		if (entry.product.is_hotel) {
			[hotelEntries addObject:entry];
		} else {
			[otherEntries addObject:entry];
		}
	}
	[[Vars appDelegate].shopCarts.entries removeAllObjects];
	[[Vars appDelegate].shopCarts.entries addObjectsFromArray:otherEntries];
}

#pragma mark - Network

- (void)getHotelPolicy:(HotelSearchRoomType *)roomType {
	GetHotelPolicy *hotelPolicy = [[GetHotelPolicy alloc] init];
	hotelPolicy.hotelId = self.hotelSearchData.hotel_description_ext.hotel_base_info.hotelID;
	hotelPolicy.roomTypeId = roomType.t_room_type_id;
	hotelPolicy.checkIn = self.hotelSearchParam.checkIn;
	hotelPolicy.checkOut = self.hotelSearchParam.checkOut;

	NSDictionary *requestDict = [BeanUtils describeAccessibleSimple:hotelPolicy];

	[Utility performSOAPRequestWithUrl:hotelPolicy.address namespace:hotelPolicy.namespace name:hotelPolicy.name parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		NSString *ret = [CocoaUtils firstValueMatchedInString:responseStr forElement:@"return"];
		if (ret) {
			NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[ret dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL];
			// NSLog(@"%@", responseDict);
			if (jsonDict) {
				WebServiceResponseJsonMapper *mapper = [[WebServiceResponseJsonMapper alloc] initWithClass:[GetHotelPolicyResponse class]];
				if (![mapper parseWithJSONObject:jsonDict]) {
					GetHotelPolicyResponse *response = mapper.response;
					if (![StringUtils isEmpty:response.error]) {
						[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error];
					} else {
						NSArray *values = [CocoaUtils allValuesMatchedInString:response.cancell_policy forElement:@"li"];
						self.hotelPolicies[@(roomType.t_room_type_id)] = [values componentsJoinedByString:@"\n"];
						[self triggerPolicyWithRoomType:roomType];
					}
				}
			}
		}
	}];
}

#pragma mark - Action

- (void)bookNow:(HotelSearchRoomType *)roomType {
	CGFloat totalCharge = 0;
	CGFloat totalTax = 0;
	CGFloat savePrice = 0;
	CartEntry *entry = [[CartEntry alloc] init];
	entry.product.p_type = 8;
	entry.product.is_room_based = YES;
	entry.product.product_id = self.hotelSearchData.pid;
	entry.product.hotel_id = self.hotelSearchData.hotel_description_ext.hotel_base_info.hotelID;
	entry.product.name = self.hotelSearchData.product_name;
	entry.product.cancellationPolicies = self.hotelPolicies[@(roomType.t_room_type_id)];
	entry.product.voucherRemark = self.hotelSearchData.hotel_description_ext.voucher_remark;
	entry.product.roomBasedPrice = [[RoomBasedPrice alloc] init];
	entry.product.roomBasedPrice.enable_child = YES;
	entry.product.piwikCategory = self.hotelSearchData.hotel_description_ext.location.searchingCity;
	entry.options[@"date"] = self.hotelSearchData.dateOption;
	entry.options[@"roomTypeId"] = @(roomType.t_room_type_id);
	entry.options[@"roomType"] = roomType.t_room_name;
	entry.roomBasedCountDatas = self.hotelSearchParam.roomInfo;
	for (SalesEntryRoom *room in entry.rooms) {
		room.room_type = roomType.t_room_name;
		room.check_in = self.hotelSearchParam.checkIn;
		room.check_out = self.hotelSearchParam.checkOut;
		room.checkin_guest = [[SoldStock alloc] init];
		room.checkin_guest.gender = @"Mr.";
		if (self.isBusHotelPackage) {
			totalCharge += (roomType.hava_tax_price - roomType.tax_save_price) * room.nights;
			totalTax += (roomType.hava_tax_price - roomType.no_tax_price) * room.nights;
			savePrice += roomType.tax_save_price * room.nights;
		} else {
			totalCharge += roomType.hava_tax_price * room.nights;
			totalTax += (roomType.hava_tax_price - roomType.t_room_price) * room.nights;
		}
	}
	entry.isBusHotelPackage = self.isBusHotelPackage;

	[[Vars appDelegate].shopCarts.entries bk_performReject:^BOOL (CartEntry *obj) {
		return obj.product.is_hotel;
	}];
	[[Vars appDelegate].shopCarts.entries addObject:entry];

	BookingReviewViewController *viewController = [[BookingReviewViewController alloc] init];
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Segue

- (void)performSegueForDescription {
	TextViewController *viewController = [[TextViewController alloc] init];
	viewController.title = IMLocalizedString(@"Description");
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	NSArray *strings = [self.hotelSearchData.hotel_description_ext.free_text_long_description componentsSeparatedByString:@"\n"];
	if (strings.count % 2 == 0) {
		NSDictionary *titleAttributes = @{ NSForegroundColorAttributeName : [UIColor blackColor], NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody] };
		NSDictionary *contentAttributes = @{ NSForegroundColorAttributeName : [UIColor darkGrayColor], NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote] };
		NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] init];
		for (int i = 0; i < strings.count; i = i + 2) {
			if (i > 0) {
				[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			}
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:strings[i] attributes:titleAttributes]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:strings[i + 1] attributes:contentAttributes]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		viewController.textView.attributedText = attributedStr;
	}
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForFeaturesAndAmenities {
	TextViewController *viewController = [[TextViewController alloc] init];
	viewController.title = IMLocalizedString(@"Features & Amenities");
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.textView.attributedText = self.fearutesAttributedString;
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForMap {
	MapViewController *viewController = [[MapViewController alloc] init];
	viewController.title = IMLocalizedString(@"Map");
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	MapViewAnnotation *annotation = [[MapViewAnnotation alloc] init];
	annotation.coordinate = CLLocationCoordinate2DMake(self.hotelSearchData.hotel_description_ext.location.latitude, self.hotelSearchData.hotel_description_ext.location.longitude);
	annotation.title = self.hotelSearchData.product_name;
	annotation.subtitle = self.hotelSearchData.hotel_description_ext.location.shortDescription;
	annotation.pinTintColor = [MKPinAnnotationView redPinColor];
	[viewController addAnnotation:annotation];
	[viewController selectAnnotation:annotation];
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForPhotos {
	MWPhotoBrowser *viewController = [[MWPhotoBrowser alloc] initWithDelegate:self];
	viewController.title = @"";
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	viewController.zoomPhotosToFill = NO;
	viewController.startOnGrid = YES;
	viewController.displayNavArrows = YES;
	viewController.displayActionButton = NO;
	viewController.navigationController.navigationBar.barTintColor = viewController.view.backgroundColor;
	[self.navigationController pushViewController:viewController animated:YES];
}

- (void)performSegueForReviews {
	IMWebViewController *viewController = [[IMWebViewController alloc] initWithURLString:self.hotelSearchData.tripadvisor_reviews_url];
	viewController.title = IMLocalizedString(@"Reviews");
	[[Vars appDelegate] applyDefaultConfigurationForViewController:viewController];
	[self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Property

- (NSAttributedString *)fearutesAttributedString {
	NSDictionary *titleAttributes = @{ NSForegroundColorAttributeName : [UIColor blackColor], NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleBody] };
	NSDictionary *contentAttributes = @{ NSForegroundColorAttributeName : [UIColor darkGrayColor], NSFontAttributeName : [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote] };
	NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] init];
	if (self.hotelSearchData.hotel_description_ext.general_descriptions.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"General Description") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.general_descriptions) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.d_locations.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Location") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.d_locations) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.location_attractions.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Location Attractions") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.location_attractions) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.recreations.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Recreation") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.recreations) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.restaurants_lounges.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Restaurants & Lounges") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.restaurants_lounges) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.services.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Services") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.services) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.accommodations.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Accommodation") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.accommodations) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.meeting_facilities.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Meeting Facilities") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.meeting_facilities) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.parkings.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Parking") attributes:titleAttributes]];
		for (NSString *text in self.hotelSearchData.hotel_description_ext.parkings) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:text attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	if (self.hotelSearchData.hotel_description_ext.amenities.count > 0) {
		if (attributedStr.length > 0) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Amenities") attributes:titleAttributes]];
		for (HotelAmenity *amenity in self.hotelSearchData.hotel_description_ext.amenities) {
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
			[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:amenity.amenity_name attributes:contentAttributes]];
		}
		[attributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	return [[NSAttributedString alloc] initWithAttributedString:attributedStr];
}

- (NSString *)hotelCheckInOutText {
	NSDate *checkInTime = [DateUtils parseDate:self.hotelSearchData.hotel_description_ext.hotel_base_info.checkInTime parsePatterns:@"HH", nil];
	NSDate *checkOutTime = [DateUtils parseDate:self.hotelSearchData.hotel_description_ext.hotel_base_info.checkOutTime parsePatterns:@"HH", nil];
	NSMutableString *string = [NSMutableString string];
	if (checkInTime) {
		[string im_appendString:IMLocalizedString(@"Check-in")];
		[string im_appendString:IMLocalizedString(PUNCTUATION_COLON)];
		[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
		[string im_appendString:[CocoaUtils localizedStringFromDate:checkInTime template:@"hmma"]];
	}
	if (checkInTime && checkOutTime) {
		[string im_appendString:IMLocalizedString(PUNCTUATION_COMMA)];
		[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
	}
	if (checkOutTime) {
		[string im_appendString:IMLocalizedString(@"Check-out")];
		[string im_appendString:IMLocalizedString(PUNCTUATION_COLON)];
		[string im_appendString:IMLocalizedString(WORD_DIVIDER_SPACE)];
		[string im_appendString:[CocoaUtils localizedStringFromDate:checkOutTime template:@"hmma"]];
	}
	return [NSString stringWithString:string];
}

#pragma mark - Private

- (void)reloadHeader {
	self.tableView.tableHeaderView = nil;
	NSString *imageUrl = self.hotelSearchData.adaptiveImageUrl;
	if (imageUrl) {
		[[SDWebImageManager sharedManager] loadImageWithURL: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];
				topImageView.userInteractionEnabled = YES;
				UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(performSegueForPhotos)];
				[topImageView addGestureRecognizer:tapGesture];
				if (self.hotelSearchData.hotel_description_ext.hotel_base_info.bestValue) {
					[topImageView addSubview:[DiscountTipTool labelForDealsWithText:IMLocalizedString(@"Exclusive Deals") font:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]]];
					topImageView.clipsToBounds = YES;
				}
				self.tableView.tableHeaderView = topImageView;
			}
		}];
	}
}

- (void)fetchPhotos {
	self.photos = [self.hotelSearchData.hotel_description_ext.images bk_map:^id (NSString *url) {
		NSString *urlString = [@"https://images.taketours.com" im_stringByAppendingString:url];
		return [MWPhoto photoWithURL:[NSURL URLWithString:urlString]];
	}];
}

- (void)togglePolicyWithRoomType:(HotelSearchRoomType *)roomType {
	if ([self isExpendedOfRoomType:roomType]) {
		[self removeTableViewCellDataForRoomType:roomType];
		[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:[self rowWhileExpendedForRoomType:roomType] inSection:1]] withRowAnimation:UITableViewRowAnimationNone];
	} else {
		if (self.hotelPolicies[@(roomType.t_room_type_id)]) {
			[self triggerPolicyWithRoomType:roomType];
		} else {
			[self getHotelPolicy:roomType];
		}
	}
}

- (void)triggerPolicyWithRoomType:(HotelSearchRoomType *)roomType {
	[self.tableView beginUpdates];
	for (HotelSearchRoomType *rt in self.hotelSearchData.t_room.t_room_types) {
		if (rt != roomType) {
			if ([self isExpendedOfRoomType:rt]) {
				[self removeTableViewCellDataForRoomType:rt];
				[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:[self rowWhileExpendedForRoomType:rt] inSection:1]] withRowAnimation:UITableViewRowAnimationNone];
			}
		}
	}
	[self insertTableViewCellDataForRoomType:roomType];
	[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:[self rowWhileExpendedForRoomType:roomType] inSection:1]] withRowAnimation:UITableViewRowAnimationNone];
	[self.tableView endUpdates];
}

- (void)buildCellDataSource {
	NSMutableArray *arrays = [NSMutableArray array];
	@weakify(self)
	if (YES) {
		NSMutableArray *array = [NSMutableArray array];
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.reuseIdentifier = NSStringFromClass([HotelSearchDetailTopCell class]);
			[data setNeedLayoutFittingHeight];
			[array addObject:data];
		}
		[arrays addObject:[NSArray arrayWithArray:array]];
	}
	if (YES) {
		NSMutableArray *array = [NSMutableArray array];
		UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
		UIFont *font2 = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2];
		CGFloat width = 0;
		if (YES) {
			UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
			button.titleLabel.font = font;
			[button setTitle:IMLocalizedString(@"Book") forState:UIControlStateNormal];
			[button sizeToFit];
			width = CGRectGetWidth(button.frame) + 5 * 2;
		}
		if (YES) {
			NSMutableString *string = [NSMutableString string];
			[string im_appendString:@"*"];
			[string im_appendString:@" "];
			[string im_appendString:IMLocalizedString(@"Prices are per room/unit and do not include taxes and service fees")];
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = [NSString stringWithString:string];
			data.textFont = font;
			data.allowsTextLineWrapping = YES;
			[array addObject:data];
		}
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.style = UITableViewCellStyleValue1;
			data.text = IMLocalizedString(@"Room Type");
			data.detailText = IMLocalizedString(@"Avg Nightly Rate");
			data.detailTextColor = [UIColor lightGrayColor];
			data.textFont = font;
			data.detailTextFont = font;
			// right inset for auto layout
			[data setAccessoryViewBlock:^UIView *(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				return [[UIView alloc] initWithFrame:CGRectMake(0, 0, width + [UIConstants defaultTableViewCellLayoutInsets].right, 0)];
			}];
			[array addObject:data];
		}
		for (HotelSearchRoomType *roomType in self.hotelSearchData.t_room.t_room_types) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.tag = 0;
			data.style = UITableViewCellStyleValue1;
			data.image = [DrawUtils tableViewCellImageWithFAKIcon:[FAKIonIcons iosInformationOutlineIconWithSize:24] fillColor:[Vars defaultTintColor]];
			data.text = roomType.t_room_name;
			data.textFont = font;
			if (self.isBusHotelPackage) {
				data.detailAttributedText = [roomType attributedTotalPriceTextWithFont:font2 roomCount:self.hotelSearchParam.roomCount nights:self.hotelSearchParam.nights additionalPrice:self.busPriceResponse.total_charge];
			} else {
				data.detailAttributedText = [roomType attributedPriceTextWithFont:font2];
			}
			data.allowsTextLineWrapping = YES;
			data.detailTextLineNumber = 2;
			[data setAccessoryViewBlock:^UIView *(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
				button.frame = CGRectMake(0, 0, width, [UIConstants defaultLabelHeight]);
				button.backgroundColor = [Vars defaultTintColor];
				button.titleLabel.font = font;
				[button setTitle:IMLocalizedString(@"Book") forState:UIControlStateNormal];
				[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
				[button bk_addEventHandler:^(id sender) {
					@strongify(self)
					[self bookNow:roomType];
				} forControlEvents:UIControlEventTouchUpInside];
				[Utility addRoundedBorderToButton:button];
				return button;
			}];
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self togglePolicyWithRoomType: roomType];
			}];
			[array addObject:data];
		}
		if (![StringUtils isEmpty:self.hotelCheckInOutText]) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = self.hotelCheckInOutText;
			data.textFont = font;
			[array addObject:data];
		}
		[arrays addObject:array];
	}
	if (YES) {
		NSMutableArray *array = [NSMutableArray array];
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = IMLocalizedString(@"Description");
			data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self performSegueForDescription];
			}];
			[array addObject:data];
		}
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = IMLocalizedString(@"Features & Amenities");
			data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self performSegueForFeaturesAndAmenities];
			}];
			[array addObject:data];
		}
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = IMLocalizedString(@"Map");
			data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self performSegueForMap];
			}];
			[array addObject:data];
		}
		if (YES) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = IMLocalizedString(@"Photos");
			data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self performSegueForPhotos];
			}];
			[array addObject:data];
		}
		if (self.hotelSearchData.tripadvisor_reviews_url) {
			TableViewCellData *data = [[TableViewCellData alloc] init];
			data.text = IMLocalizedString(@"Reviews");
			data.accessoryType = UITableViewCellAccessoryDisclosureIndicatorRight;
			[data setDidSelectBlock:^(UITableView *tableView, NSIndexPath *indexPath, TableViewCellData *data) {
				@strongify(self)
				[self performSegueForReviews];
			}];
			[array addObject:data];
		}
		[arrays addObject:[NSArray arrayWithArray:array]];
	}
	self.cellDataArrays = [NSArray arrayWithArray:arrays];
}

- (void)removeTableViewCellDataForRoomType:(HotelSearchRoomType *)roomType {
	NSMutableArray *array = self.cellDataArrays[1];
	[array removeObjectAtIndex:[self rowWhileExpendedForRoomType:roomType]];
}

- (void)insertTableViewCellDataForRoomType:(HotelSearchRoomType *)roomType {
	UIFont *font1 = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
	UIFont *font2 = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1];
	NSAttributedString *checkIcon = [DrawUtils attributedStringWithFAKIcon:[FAKFontAwesome checkIconWithSize:font2.pointSize] fillColor:[UIColor redColor]];
	NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
	for (HotelSearchRoomTypeBoardbase *boardBase in roomType.t_boardbases) {
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:boardBase.bdprice == 0 ? IMLocalizedString(@"FREE") : [@"$" stringByAppendingFormat:@"%g", boardBase.bdprice] attributes:@{ NSForegroundColorAttributeName : [CocoaUtils colorWithRGBs:StandardColorOrange], NSFontAttributeName : font2 }]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:boardBase.bdname attributes:@{ NSFontAttributeName : font2 }]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
		[attributedString appendAttributedString:checkIcon];
		if (boardBase != roomType.t_boardbases.lastObject) {
			[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		}
	}
	if (roomType.t_boardbases.count > 0 && roomType.promotion_xml) {
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
	}
	HotelSearchRoomTypePromotion *promotion = roomType.promotion_xml;
	if (promotion) {
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:promotion.name attributes:@{ NSForegroundColorAttributeName : [CocoaUtils colorWithRGBs:StandardColorOrange], NSFontAttributeName : font2 }]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:promotion.info attributes:@{ NSFontAttributeName : font2 }]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
		[attributedString appendAttributedString:checkIcon];
	}
	NSDictionary *titleAttributes = @{ NSForegroundColorAttributeName : [UIColor blackColor], NSFontAttributeName : font1 };
	NSDictionary *contentAttributes = @{ NSForegroundColorAttributeName : [UIColor darkGrayColor], NSFontAttributeName : font2 };
	if (roomType.facilities.count > 0) {
		if (attributedString.length > 0) {
			[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\n"]];
		}
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Facilities") attributes:titleAttributes]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:[[roomType.facilities valueForKeyPath:@"name"] componentsJoinedByString:@", "] attributes:contentAttributes]];
	}
	if (YES) {
		if (attributedString.length > 0) {
			[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\n"]];
		}
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Cancellation Policies") attributes:titleAttributes]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.hotelPolicies[@(roomType.t_room_type_id)] attributes:contentAttributes]];
	}
	if (![StringUtils isEmpty:self.hotelSearchData.hotel_description_ext.voucher_remark]) {
		if (attributedString.length > 0) {
			[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n\n"]];
		}
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Special Remarks") attributes:titleAttributes]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@"\n"]];
		[attributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.hotelSearchData.hotel_description_ext.voucher_remark attributes:contentAttributes]];
	}

	NSMutableArray *array = self.cellDataArrays[1];
	TableViewCellData *data = [[TableViewCellData alloc] init];
	data.tag = 1;
	data.attributedText = attributedString;
	data.allowsTextLineWrapping = YES;
	[array insertObject:data atIndex:[self rowWhileExpendedForRoomType:roomType]];
}

- (BOOL)isExpendedOfRoomType:(HotelSearchRoomType *)roomType {
	NSMutableArray *array = self.cellDataArrays[1];
	NSInteger row = [self rowWhileExpendedForRoomType:roomType];
	if (array.count <= row) {
		return NO;
	}
	TableViewCellData *data = array[row];
	return data.tag == 1;
}

- (NSInteger)rowWhileExpendedForRoomType:(HotelSearchRoomType *)roomType {
	return 2 + [self.hotelSearchData.t_room.t_room_types indexOfObject:roomType] + 1;
}

#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];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([HotelSearchDetailTopCell class])]) {
		HotelSearchDetailTopCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([HotelSearchDetailTopCell class])];
		cell.productNameLabel.text = self.hotelSearchData.product_name;
		cell.starRatingLabel.attributedText = [self.hotelSearchData attributedRatingTextWithFont:cell.starRatingLabel.font];
		[cell setTripAdvisorImageWithURLString:self.hotelSearchData.tripadvisor_image_url];
		if (![StringUtils isEmpty:self.hotelSearchData.hotel_description_ext.ref_point.shortDescription]) {
			NSMutableAttributedString *pointAttributedStr = [[NSMutableAttributedString alloc] init];
			if ([self.hotelSearchData.hotel_description_ext.ref_point.type isEqualToString:@"airport"]) {
				[pointAttributedStr appendAttributedString:[DrawUtils attributedStringWithFAKIcon:[FAKFontAwesome planeIconWithSize:cell.addressLabel.font.pointSize] fillColor:[UIColor lightGrayColor]]];
				[pointAttributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
			}
			[pointAttributedStr appendAttributedString:[[NSAttributedString alloc] im_initWithString:self.hotelSearchData.hotel_description_ext.ref_point.shortDescription]];
			cell.pointDescriptionLabel.attributedText = [[NSAttributedString alloc] initWithAttributedString:pointAttributedStr];
		}
		cell.amenityImageView.image = [self.hotelSearchData concatenateAmenityImageToWidth:cell.addressLabel.font.pointSize tintColor:[CocoaUtils colorWithRGBs:StandardColorBlue] borderWidth:cell.addressLabel.font.pointSize / 5];
		cell.addressLabel.text = self.hotelSearchData.hotel_description_ext.location.shortDescription;
		[cell.addressButton removeTarget:self action:@selector(performSegueForMap) forControlEvents:UIControlEventTouchUpInside];
		[cell.addressButton addTarget:self action:@selector(performSegueForMap) forControlEvents:UIControlEventTouchUpInside];
		[cell setNeedsUpdateConstraints];
		return cell;
	}
	return [UIToolkit tableView:tableView atIndexPath:indexPath cellWithData:data];
}

#pragma mark - Table view delegate

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
	TableViewCellData *data = self.cellDataArrays[indexPath.section][indexPath.row];
	if ([data.reuseIdentifier isEqualToString:NSStringFromClass([HotelSearchDetailTopCell class])]) {
		return [UIToolkit instantiateRowHeightForTableViewCellWithNibName:NSStringFromClass([HotelSearchDetailTopCell 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];
}

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

#pragma mark - <MWPhotoBrowserDelegate>

- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
	return self.photos.count;
}

- (id<MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
	return self.photos[index];
}

- (id<MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
	return self.photos[index];
}

@end
