#import "AppDelegate.h"
#import "Lang.h"
#import "SDK.h"
#import "BeanUtils.h"
#import "CocoaUtils.h"
#import "NetUtils.h"
#import "RandomUtils.h"
#import "UserNotificationsManager.h"
#import "CustomNavigationController.h"
#import "UIConstants.h"
#import "UIToolkit.h"
#import "UserApi.h"
#import <UserNotifications/UserNotifications.h>
#import <Crashlytics/Crashlytics.h>
#import <Fabric/Fabric.h>
#import <PayPal-iOS-SDK/PayPalMobile.h>
#import <PiwikTracker/PiwikTracker.h>
#ifdef POD_OF_Firebase
 #import <Firebase/Firebase.h>
#endif
#ifdef POD_OF_FBSDKCoreKit
 #import <FBSDKCoreKit/FBSDKCoreKit.h>
#endif
#ifdef POD_OF_FBSDKLoginKit
 #import <FBSDKLoginKit/FBSDKLoginKit.h>
#endif
#ifdef POD_OF_GoogleSignIn
 #import <GoogleSignIn/GoogleSignIn.h>
#endif
#import "Utility.h"
#import "AppDelegate+UserNotifications.h"
#import "AppNotification.h"
#import "AppTracker.h"
#import "BusUnit.h"
#import "PrefetchLoginPostDataResponseJsonMapper.h"
#import "LaunchScreenViewController.h"
#import "LoginViewController.h"
#import "TabBarViewController.h"
#import "Vars.h"

@interface AppDelegate () <UIApplicationDelegate> {
	BOOL _needReloadTabBar;
}
@end

@implementation AppDelegate

#pragma mark - Application delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	application.applicationIconBadgeNumber = 0;
	self.remoteNotificationUserInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
#ifdef POD_OF_FBSDKCoreKit
	[[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
#endif
#if defined POD_OF_Firebase && defined POD_OF_GoogleSignIn
	[FIRApp configure];
	[GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
#endif
	[PayPalMobile initializeWithClientIdsForEnvironments:@{ PayPalEnvironmentProduction : [Vars paypalLiveClientId], PayPalEnvironmentSandbox : [Vars paypalSandboxClientId] }];
	[AppTracker sharedInstanceWithSiteID:[Vars piwikSiteId] baseURL:[NSURL URLWithString:[Vars piwikBaseUrl]]];
	[Fabric with:@[[Crashlytics class]]];
	[Utility configureRaterFlow];
	[self initPrivate];
	[self customizeAppearance];
	[self resetPreferredLanguage];
	[self resetUserDefaults];
	[self launchOrSimulate];
	return YES;
}


- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
	return [self internallyApplication:app openURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
	application.applicationIconBadgeNumber = 0;
#ifdef POD_OF_FBSDKCoreKit
	[FBSDKAppEvents activateApp];
#endif
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
}

#pragma mark - Property

- (void)setLoginUser:(Vendor *)loginUser {
	NSInteger oldFlag = 0;
	if (_loginUser.is_support) {
		oldFlag = 6;
	} else if (_loginUser.is_vendor) {
		oldFlag = 3;
	} else if (_loginUser.is_bus_driver) {
		oldFlag = 2;
	} else {
		oldFlag = 1;
	}
	NSInteger newFlag = 0;
	if (loginUser.is_support) {
		newFlag = 6;
	} else if (loginUser.is_vendor) {
		newFlag = 3;
	} else if (loginUser.is_bus_driver) {
		newFlag = 2;
	} else {
		newFlag = 1;
	}
	_needReloadTabBar = oldFlag != newFlag;
	_loginUser = loginUser;
	self.shopCarts.bookGoods.accessToken = loginUser.cookie_string;
}

#pragma mark - Public
- (void)firstLoadLogin {
	LoginViewController *viewController = [[LoginViewController alloc] init];
	viewController.firstLaunchV = YES;
	CustomNavigationController *nav = [[CustomNavigationController alloc]initWithRootViewController:viewController];
	self.window.rootViewController = nav;
}

- (void)dashboard {
	if ([self.window.rootViewController isKindOfClass:[TabBarViewController class]]) {
		TabBarViewController *tabbarController = self.window.rootViewController;
		[tabbarController reloadTabBarIfNeeded:_needReloadTabBar];
		if (_needReloadTabBar) {
			_needReloadTabBar = NO;
		}
	} else {
		self.window.rootViewController = [[TabBarViewController alloc] init];
		[AppNotification handleNotification:self.remoteNotificationUserInfo];
	}
	if (self.loginUser) {
		[[UIApplication sharedApplication] registerForRemoteNotifications];
	}
}

- (void)logout {
	[CocoaUtils showConfirmWithTitle:IMLocalizedString(@"Logout") message:IMLocalizedString(@"Logout will not delete your bookings, the history will still be there when you login next time.") dismissalHandler:^{
		
		Logout *logout = [[Logout alloc] init];
		logout.userAppId = self.loginUser.user_app_id ;
		
		NSDictionary *requestDict = [BeanUtils describeAccessibleSimple:logout];
		[Utility performRESTRequestWithMethod:@"POST" url:logout.address parameters:requestDict success:^(id jsonObject) {
			LogoutResponse *response = [LogoutResponse yy_modelWithJSON:jsonObject];
			if (!response.errorCode) {
				[PayPalMobile clearAllUserData];
#ifdef POD_OF_FBSDKLoginKit
				FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
				[loginManager logOut];
#endif
#ifdef POD_OF_GoogleSignIn
				[[GIDSignIn sharedInstance] signOut];
#endif
				NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
				[userDefaults removeObjectForKey:UserDefaultsKeyUserID];
				self.loginUser = nil;
				NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
				[notificationCenter postNotificationName:SegueDidPerformNotification object:TabBarItemHome];
				[notificationCenter postNotificationName:LoginStatusDidChangeNotification object:nil];
				[self dashboard];
			}
		}];
	}];
}

- (void)applyDefaultConfigurationForViewController:(UIViewController *)viewController {
	viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:NULL];
}

- (void)getSearchDataSource:(NSString *)name {
	if ([name isEqualToString:@"Bus + Hotel"] && !self.coreData.busSearchDataSource && !self.coreData.hotelSearchDataSource) {
		[NetUtils beginTransation];
		NSMutableArray *batched = [NSMutableArray array];
		if (YES) {
			GetSearchDataSource *getSearchDataSource = [[GetSearchDataSource alloc] init];
			getSearchDataSource.typeName = @"Bus";

			NSDictionary *requestDict = [Utility perlParamXml:[getSearchDataSource innerXML] action:getSearchDataSource.name];
			// NSLog(@"%@", requestDict);
			id obj = [Utility getJSONFromRequestWithMethod:@"GET" url:getSearchDataSource.address parameters:requestDict beforeSend:nil success:^(id jsonObject) {
				self.coreData.busSearchDataSource = jsonObject;
			} complete:nil];

			[batched addObject:obj];
		}
		if (YES) {
			GetSearchDataSource *getSearchDataSource = [[GetSearchDataSource alloc] init];
			getSearchDataSource.typeName = @"Hotel";

			NSDictionary *requestDict = [Utility perlParamXml:[getSearchDataSource innerXML] action:getSearchDataSource.name];
			// NSLog(@"%@", requestDict);
			id obj = [Utility getJSONFromRequestWithMethod:@"GET" url:getSearchDataSource.address parameters:requestDict beforeSend:nil success:^(id jsonObject) {
				self.coreData.hotelSearchDataSource = jsonObject;
			} complete:nil];

			[batched addObject:obj];
		}
		UIViewController *this = [CocoaUtils topMostViewController];
		[CocoaUtils showBusyIndicator:this.view];
		[NetUtils performBatchOf:batched completion:^{
			[CocoaUtils hideBusyIndicator:this.view];
		}];
	} else if ([name containsString:@"Bus"] && !self.coreData.busSearchDataSource) {
		if ([Vars clientDomainId] > 0 && [Vars clientDomainId] != 3838) {
			GetAllBusRoute *getAllBusRoute = [[GetAllBusRoute alloc] init];
			getAllBusRoute.vendorNo = [Vars clientDomainId];

			NSDictionary *requestDict = [Utility perlParamXml:[getAllBusRoute innerXML] action:getAllBusRoute.name];
			// NSLog(@"%@", requestDict);
			[Utility getJSONFromRequestWithMethod:@"GET" url:getAllBusRoute.address parameters:requestDict success:^(id jsonObject) {
				self.coreData.busSearchDataSource = jsonObject ? @{ @"pairs" : jsonObject } : nil;
			}];
		} else {
			GetSearchDataSource *getSearchDataSource = [[GetSearchDataSource alloc] init];
			getSearchDataSource.typeName = @"Bus";

			NSDictionary *requestDict = [Utility perlParamXml:[getSearchDataSource innerXML] action:getSearchDataSource.name];
			// NSLog(@"%@", requestDict);
			[Utility getJSONFromRequestWithMethod:@"GET" url:getSearchDataSource.address parameters:requestDict success:^(id jsonObject) {
				self.coreData.busSearchDataSource = jsonObject;
			}];
		}
	} else if ([name containsString:@"Hotel"] && !self.coreData.hotelSearchDataSource) {
		GetSearchDataSource *getSearchDataSource = [[GetSearchDataSource alloc] init];
		getSearchDataSource.typeName = @"Hotel";

		NSDictionary *requestDict = [Utility perlParamXml:[getSearchDataSource innerXML] action:getSearchDataSource.name];
		// NSLog(@"%@", requestDict);
		[Utility getJSONFromRequestWithMethod:@"GET" url:getSearchDataSource.address parameters:requestDict success:^(id jsonObject) {
			self.coreData.hotelSearchDataSource = jsonObject;
		}];
	}
}

- (void)prefetchLoginPostData:(void (^) (void))completion {
	PrefetchLoginPostData *prefetchLoginPostData = [[PrefetchLoginPostData alloc] init];

	NSDictionary *requestDict = [Utility perlParamXml:[prefetchLoginPostData innerXML] action:prefetchLoginPostData.name];
	// NSLog(@"%@", requestDict);
	[Utility getXMLFromRequestWithMethod:@"GET" url:prefetchLoginPostData.address parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		PrefetchLoginPostDataResponseJsonMapper *mapper = [[PrefetchLoginPostDataResponseJsonMapper alloc] init];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			PrefetchLoginPostDataResponse *response = mapper.response;
			if (response.error_code > 0) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error_message];
			} else if (completion) {
				completion();
			}
		}
	}];
}

- (void)callPhone {
	if ([Vars rangedPhones]) {
		NSMutableArray *phoneValues = [NSMutableArray array];
		NSMutableArray *phoneTexts = [NSMutableArray array];
		for (NSString *key in [[Vars rangedPhones].allKeys sortedArrayUsingSelector: @selector(localizedCaseInsensitiveCompare:)]) {
			[phoneValues addObject:[Vars rangedPhones][key]];
			[phoneTexts addObject:[NSString stringWithFormat:@"%@ (%@)", [Vars rangedPhones][key], key]];
		}
		[CocoaUtils showMessageBoxWithTitle:IMLocalizedString(@"Call") message:nil cancelActionTitle:IMLocalizedString(@"Cancel") otherActionTitles:phoneTexts actionHandler:^(NSInteger buttonIndex) {
			if (buttonIndex != -1) {
				[CocoaUtils callPhoneNumber:phoneValues[buttonIndex]];
			}
		}];
	} else if ([Vars phone]) {
		[CocoaUtils callPhoneNumber:[Vars phone]];
	}
}


#pragma mark - Private

- (void)initPrivate {
	self.coreData = [[MyCoreData alloc] init];
	self.shopCarts = [[ShopCarts alloc] init];
}

- (void)customizeAppearance {
	[UIWindow appearance].tintColor = [Vars defaultTintColor];

	[UITableView appearance].rowHeight = [UIConstants defaultTableViewRowHeight];
	[UITableView appearance].estimatedRowHeight = [UIConstants defaultTableViewRowHeight];
	[UITableView appearance].estimatedSectionHeaderHeight = 0;
	[UITableView appearance].estimatedSectionFooterHeight = 0;
	[UITableView appearance].tableFooterView = [[UIView alloc] init];

	// background
	[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[CustomNavigationController class]]].barTintColor = [Vars defaultTintColor];
	// title
	[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[CustomNavigationController class]]].titleTextAttributes = @{ NSForegroundColorAttributeName : [UIColor whiteColor] };
	// system/image item
	[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[CustomNavigationController class]]].tintColor = [UIColor whiteColor];
	// title item
	[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[CustomNavigationController class]]] setTitleTextAttributes:@{ NSForegroundColorAttributeName : [UIColor whiteColor] } forState:UIControlStateNormal];
	
	[UISwitch appearance].onTintColor = [Vars defaultTintColor];
}

- (void)resetPreferredLanguage {
	if (![IMLocalization sharedInstance].hasPreferredLanguage) {
		[IMLocalization sharedInstance].language = [NSBundle mainBundle].infoDictionary[@"CFBundleDevelopmentRegion"];
	}
}

- (void)resetUserDefaults {
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	if (![userDefaults objectForKey:UserDefaultsKeyUserNotificationsEnabled]) {
		[userDefaults setBool:YES forKey:UserDefaultsKeyUserNotificationsEnabled];
	}
}

- (void)launchOrSimulate {
#if DEBUG
	if (YES) {
		UIViewController *viewController = [BusUnit simulatedViewController];
		if (viewController) {
			self.window.rootViewController = viewController;
			return;
		}
	}
#endif
	[self launch];
}

- (void)launch {
	self.window.rootViewController = [[LaunchScreenViewController alloc] init];
}

- (BOOL)internallyApplication:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
	BOOL isGoogleUrl = NO, isFaceBookUrl = NO;
#ifdef POD_OF_GoogleSignIn
	isGoogleUrl = [[GIDSignIn sharedInstance] handleURL:url sourceApplication:sourceApplication                                     annotation:annotation];
#endif
#ifdef POD_OF_FBSDKCoreKit
	isFaceBookUrl = [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation];
#endif
	return isGoogleUrl||isFaceBookUrl;
}

@end
