//
//  GetItineraryByIdResponseJsonMapper.m
//  GotoBus
//
//  Created by 包光清 on 2019/1/3.
//

#import "GetItineraryByIdResponseJsonMapper.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import <BlocksKit/BlocksKit.h>
#import <RestKit/RKObjectMappingOperationDataSource.h>
#import "Sales.h"
#import "Airport.h"
#import "SalesEntryRoom.h"
#import "AirportStop.h"
#import "Vars.h"

@implementation GetItineraryByIdResponseJsonMapper


- (instancetype)init {
	if (self = [super init]) {
		RKAttributeMapping *descMapping = [RKAttributeMapping attributeMappingFromKeyPath:@"description" toKeyPath:@"desc"];
		descMapping.propertyValueClass = [NSDictionary class];
		
		RKObjectMapping *passportMapping = [RKObjectMapping mappingForClass:[Passport class]];
		[passportMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Passport class]]];
		
		RKObjectMapping *flightMapping = [RKObjectMapping mappingForClass:[FlightInfo class]];
		[flightMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[FlightInfo class]]];
		
		RKObjectMapping *stockMapping = [RKObjectMapping mappingForClass:[SoldStock class]];
		[stockMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[SoldStock class]]];
		[stockMapping addPropertyMapping:descMapping];
		[stockMapping addRelationshipMappingWithSourceKeyPath:@"passport" mapping:passportMapping];
		[stockMapping addRelationshipMappingWithSourceKeyPath:@"flight_info" mapping:flightMapping];
		
		RKObjectMapping *roomMapping = [RKObjectMapping mappingForClass:[SalesEntryRoom class]];
		[roomMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[SalesEntryRoom class]]];
		[roomMapping addRelationshipMappingWithSourceKeyPath:@"stocks" mapping:stockMapping];
		[roomMapping addRelationshipMappingWithSourceKeyPath:@"checkin_guest" mapping:stockMapping];
		
		RKObjectMapping *entryMapping = [RKObjectMapping mappingForClass:[SalesEntry class]];
		[entryMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[SalesEntry class]]];
		[entryMapping addRelationshipMappingWithSourceKeyPath:@"stocks" mapping:stockMapping];
		[entryMapping addRelationshipMappingWithSourceKeyPath:@"rooms" mapping:roomMapping];
		
		RKObjectMapping *orderMapping = [RKObjectMapping mappingForClass:[Sales class]];
		[orderMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Sales class]]];
		[orderMapping addRelationshipMappingWithSourceKeyPath:@"entries" mapping:entryMapping];
		
		RKObjectMapping *statusInfoMapping = [RKObjectMapping mappingForClass:[BusStatusInfo class]];
		[statusInfoMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[BusStatusInfo class]]];
		
		RKObjectMapping *busStopMapping = [RKObjectMapping mappingForClass:[BusStop class]];
		[busStopMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[BusStop class]]];
		
		RKObjectMapping *airportStopMapping = [RKObjectMapping mappingForClass:[AirportStop class]];
		[airportStopMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[AirportStop class]]];
		
		RKObjectMapping *labelMapping = [RKObjectMapping mappingForClass:[Label class]];
		[labelMapping addAttributeMappingsFromDictionary:[CocoaUtils dictionaryForKeys:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Label class]] retainEntries:@{ @"label_name" : @"name" }]];
//		[labelMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Label class]]];
		
		RKObjectMapping *productMapping = [RKObjectMapping mappingForClass:[Product class]];
//		[productMapping addAttributeMappingsFromDictionary:[CocoaUtils dictionaryForKeys:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Product class]] retainEntries:@{ @"product_vendor" : @"vendor"}]];
		[productMapping addAttributeMappingsFromArray:[[BeanUtils keysForAccessibleSimplePropertyWithClass:[Product class]] arrayByAddingObject:@"not_need_flight_options"]];
		[productMapping addRelationshipMappingWithSourceKeyPath:@"labels" mapping:labelMapping];
		[productMapping addRelationshipMappingWithSourceKeyPath:@"stops" mapping:busStopMapping];
		[productMapping addRelationshipMappingWithSourceKeyPath:@"airport_stops" mapping:airportStopMapping];
		
		RKObjectMapping *vendorMapping = [RKObjectMapping mappingForClass:[Vendor class]];
		[vendorMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Vendor class]]];
		
		RKObjectMapping *busStationMapping = [RKObjectMapping mappingForClass:[BusStation class]];
		[busStationMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[BusStation class]]];
		
		RKObjectMapping *airportMapping = [RKObjectMapping mappingForClass:[Airport class]];
		[airportMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Airport class]]];
		
		RKObjectMapping *destinationMapping = [RKObjectMapping mappingForClass:[Destination class]];
		[destinationMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[Destination class]]];
		
		RKObjectMapping *getItineraryByIdMapping = [RKObjectMapping mappingForClass:[GetItineraryByIdResponse class]];
		[getItineraryByIdMapping addAttributeMappingsFromArray:[BeanUtils keysForAccessibleSimplePropertyWithClass:[GetItineraryByIdResponse class]]];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"orders" mapping:orderMapping];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"bus_status_infos" mapping:statusInfoMapping];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"products" mapping:productMapping];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"vendors" mapping:vendorMapping];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"bus_stations" mapping:busStationMapping];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"airports" mapping:airportMapping];
		[getItineraryByIdMapping addRelationshipMappingWithSourceKeyPath:@"destinations" mapping:destinationMapping];
		
		self.objectMapping = getItineraryByIdMapping;
	}
	return self;
}

#pragma mark - Public

- (NSError *)parseWithJSONObject:(id)jsonObject {
	self.response = [[GetItineraryByIdResponse alloc] init];
	RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:jsonObject destinationObject:self.response mapping:self.objectMapping];
	RKObjectMappingOperationDataSource *mappingOperationDataSource = [[RKObjectMappingOperationDataSource alloc] init];
	mappingOperation.dataSource = mappingOperationDataSource;
	NSError *error = nil;
	if ([mappingOperation performMapping:&error]) {
		NSArray *orders = self.response.orders;
		NSArray *products = self.response.products;
		NSArray *vendors = self.response.vendors;
		NSArray *stations = self.response.bus_stations;
		NSArray *airports = self.response.airports;
		NSArray *destinations = self.response.destinations;
		NSArray *busStatusInfos = self.response.bus_status_infos;
		NSDictionary *vendorHash = [NSDictionary dictionaryWithObjects:vendors forKeys:[vendors valueForKeyPath:@"id"]];
		for (Product *product in products) {
			product.vendor_obj = vendorHash[@(product.product_vendor)];
		}
		NSDictionary *destinationHash = [NSDictionary dictionaryWithObjects:destinations forKeys:[destinations valueForKeyPath:@"folder_id"]];
		for (BusStation *station in stations) {
			station.destination = destinationHash[@(station.station_city)];
		}
		NSDictionary *stationHash = [NSDictionary dictionaryWithObjects:stations forKeys:[stations valueForKeyPath:@"aid"]];
		for (Product *product in products) {
			for (BusStop *stop in product.stops) {
				stop.station = stationHash[@(stop.bss_id)];
			}
		}
		NSDictionary *airportHash = [NSDictionary dictionaryWithObjects:airports forKeys:[airports valueForKeyPath:@"aid"]];
		for (Product *product in products) {
			for (AirportStop *stop in product.airport_stops) {
				stop.airport = airportHash[@(stop.airport_id)];
			}
		}
		NSDictionary *productHash = [NSDictionary dictionaryWithObjects:products forKeys:[products valueForKey:@"product_id"]];
		for (BusStatusInfo *statusInfo in busStatusInfos) {
			statusInfo.product = productHash[@(statusInfo.pid)];
		}
		NSDictionary *statusInfoHash = [NSDictionary dictionaryWithObjects:busStatusInfos forKeys:[busStatusInfos bk_map:^id (BusStatusInfo *statusInfo) {
			return [NSString stringWithFormat:@"%d%@", statusInfo.pid, statusInfo.service_date];
		}]];
		for (Sales *order in orders) {
			for (SalesEntry *entry in order.entries) {
				entry.order = order;
				entry.product = productHash[@(entry.pid)];
				NSString *busStatusInfoKey = [NSString stringWithFormat:@"%d%@", entry.pid, entry.service_date];
				entry.bus_status_info = statusInfoHash[busStatusInfoKey];
				for (SoldStock *stock in entry.serialStocks) {
					stock.entry = entry;
				}
			}
		}

	}
	return error;
}

@end
