#import "LoginViewController.h"
#import "Lang.h"
#import "SDK.h"
#import "AnswersManager.h"
#import "CocoaUtils.h"
#import "DrawUtils.h"
#import "UIConstants.h"
#import <BlocksKit/BlocksKit+UIKit.h>
#if defined POD_OF_FBSDKCoreKit && defined POD_OF_FBSDKLoginKit
 #import <FBSDKCoreKit/FBSDKCoreKit.h>
 #import <FBSDKLoginKit/FBSDKLoginKit.h>
#endif
#import <IQKeyboardManager/IQKeyboardManager.h>
#import <IQKeyboardManager/IQUIView+IQKeyboardToolbar.h>
#import <PureLayout/PureLayout.h>
#import "Utility.h"
#import "CustomTextFieldView.h"
#import "PerlWS.h"
#import "LoginResponseJsonMapper.h"
#import "FacebookLoginResponseJsonMapper.h"
#import "JoinViewController.h"
#import "Vars.h"
#import "ResetPassWordViewController.h"

@interface LoginViewController ()
#if defined POD_OF_FBSDKCoreKit && defined POD_OF_FBSDKLoginKit
<FBSDKLoginButtonDelegate>
#endif

@property (nonatomic, weak) IBOutlet CustomTextFieldView *userView;
@property (nonatomic, weak) IBOutlet CustomTextFieldView *pwdView;
@property (nonatomic, weak) IBOutlet UIButton *loginButton;
@property (weak, nonatomic) IBOutlet UIStackView *buttonStackView;
@property (weak, nonatomic) IBOutlet UIButton *forgetPasswordButton;


@property (nonatomic, strong) id segueObject;
@property (nonatomic, assign) BOOL popAnimated;
@property (nonatomic, copy) void (^destructiveBlock) (void);
@property (nonatomic, strong) NSString *otherButtonTitle;
@property (nonatomic, copy) void (^otherButtonHandler) (UIButton *button);

@property (nonatomic, strong, readonly) UITextField *usernameField;
@property (nonatomic, strong, readonly) UITextField *passwordField;
@property (nonatomic, assign, readonly) BOOL allowsFacebookLogin;

- (IBAction)clickLogin:(id)sender;
- (IBAction)forgetPassword:(id)sender;
- (IBAction)join:(id)sender;
- (IBAction)hideKeyboard:(id)sender;

@end

@implementation LoginViewController

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

- (void)viewDidLoad {
	[super viewDidLoad];

	self.userView.asteriskLabel.hidden = YES;
	self.usernameField.placeholder = IMLocalizedString(@"Email or ID");
	self.usernameField.autocapitalizationType = UITextAutocapitalizationTypeNone;
	self.usernameField.autocorrectionType = UITextAutocorrectionTypeNo;
	[self.usernameField.keyboardToolbar.doneBarButton setTarget:self action:@selector(resignLogin:)];

	self.pwdView.asteriskLabel.hidden = YES;
    self.passwordField.placeholder = IMLocalizedString(@"Password");
	self.passwordField.im_textContentType = IMTextContentTypePassword;
	self.passwordField.autocapitalizationType = UITextAutocapitalizationTypeNone;
	self.passwordField.autocorrectionType = UITextAutocorrectionTypeNo;
	self.passwordField.secureTextEntry = YES;
	self.passwordField.clearsOnBeginEditing = YES;
	[self.passwordField.keyboardToolbar.doneBarButton setTarget:self action:@selector(resignLogin:)];

    [self.forgetPasswordButton setTitle:IMLocalizedString(@"Forgot Password?") forState:UIControlStateNormal];
    
	self.loginButton.backgroundColor = [Vars defaultTintColor];
	[self.loginButton setTitle:IMLocalizedString(@"Login") forState:UIControlStateNormal];
	[Utility addRoundedBorderToButton:self.loginButton];

#if defined POD_OF_FBSDKCoreKit && defined POD_OF_FBSDKLoginKit
	if (self.allowsFacebookLogin) {
        FBSDKLoginButton *fbLoginButton = nil;
        [self facebookLogout];
        fbLoginButton = [[FBSDKLoginButton alloc] init];
        [fbLoginButton removeConstraints:fbLoginButton.constraints];
        [self.buttonStackView addArrangedSubview:fbLoginButton];
        fbLoginButton.readPermissions = @[@"public_profile", @"email"];
        fbLoginButton.loginBehavior = FBSDKLoginBehaviorSystemAccount;
        fbLoginButton.delegate = self;
	}
#endif

    UIButton *signUpButton = [UIButton buttonWithType:UIButtonTypeCustom];
    NSMutableAttributedString *signUpAttributedString = [[NSMutableAttributedString alloc] init];
	[signUpAttributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:[NSString stringWithFormat:IMLocalizedString(@"New to %@?"), [Vars site_name]] attributes:@{NSForegroundColorAttributeName:[UIColor darkGrayColor]}] ];
	[signUpAttributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:@" "]];
	[signUpAttributedString appendAttributedString:[[NSAttributedString alloc] im_initWithString:IMLocalizedString(@"Register") attributes:@{NSForegroundColorAttributeName:[Vars defaultTintColor]}]];
    [signUpButton setAttributedTitle:signUpAttributedString forState:UIControlStateNormal];
    [signUpButton addTarget:self action:@selector(join:) forControlEvents:UIControlEventTouchUpInside];
    [self.buttonStackView addArrangedSubview:signUpButton];
    
    UIButton *otherButton = nil;
    if (self.otherButtonTitle && self.otherButtonHandler) {
        if (!otherButton) {
            otherButton = [UIButton buttonWithType:UIButtonTypeSystem];
            [self.buttonStackView addArrangedSubview:otherButton];
            [otherButton autoSetDimension:ALDimensionHeight toSize:[UIConstants defaultTableViewRowHeight]];
        }
        otherButton.backgroundColor = [Vars defaultTintColor];
        otherButton.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont buttonFontSize]];
        [otherButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        [otherButton setTitle:self.otherButtonTitle forState:UIControlStateNormal];
        [otherButton bk_removeEventHandlersForControlEvents:UIControlEventTouchUpInside];
        [otherButton bk_addEventHandler:self.otherButtonHandler forControlEvents:UIControlEventTouchUpInside];
        [Utility addRoundedBorderToButton:otherButton];
    }
}

- (void)viewWillAppear:(BOOL)animated {
	[super viewWillAppear:animated];

	self.usernameField.text = nil;
	self.passwordField.text = nil;
}

- (void)viewDidDisappear:(BOOL)animated {
	[super viewDidDisappear:animated];

	[CocoaUtils proxyTopMostViewController:nil];
}

#pragma mark - Public

- (void)performSegueWithObject:(id)object popAnimated:(BOOL)animated {
	self.segueObject = object;
	self.popAnimated = animated;
}

- (void)setOtherButtonWithTitle:(NSString *)title addEventHandler:(void (^) (UIButton *button))handler {
	self.otherButtonTitle = title;
	self.otherButtonHandler = handler;
}

#pragma mark - Property

- (UITextField *)usernameField {
	return self.userView.textField;
}

- (UITextField *)passwordField {
	return self.pwdView.textField;
}

- (BOOL)allowsFacebookLogin {
	return ![Vars is_cn_website];
}

#pragma mark - Action

- (IBAction)forgetPassword:(id)sender {
    ResetPassWordViewController *resetPasswordViewController = [[ResetPassWordViewController alloc] init];
    [self.navigationController pushViewController:resetPasswordViewController animated:YES];
}

- (IBAction)clickLogin:(id)sender {
	if (![self validateLogin:NO]) {
		return;
	}
	[self login];
}


- (IBAction)join:(id)sender {
	JoinViewController *viewController = [[JoinViewController alloc] init];
	[viewController performSegueWithObject:self.segueObject popAnimated:self.popAnimated];
	[viewController setDestructiveBlock:self.destructiveBlock];
	[self.navigationController pushViewController:viewController animated:YES];
}

- (IBAction)hideKeyboard:(id)sender {
	[self.view endEditing:YES];
	if ([self validateLogin:YES]) {
		[self login];
	}
}

- (void)resignLogin:(UITextField *)textField {
	if ([textField isFirstResponder]) {
		[textField resignFirstResponder];
	}
	if ([self validateLogin:YES]) {
		[self login];
	}
}

#pragma mark - Network

- (void)login {
	Login *login = [[Login alloc] init];
	login.username = self.usernameField.text;
	login.password = self.passwordField.text;

	NSDictionary *requestDict = [Utility perlParamXml:[login innerXML] action:login.name];
	// NSLog(@"%@", requestDict);
	[Utility getXMLFromRequestWithMethod:@"GET" url:login.address parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		LoginResponseJsonMapper *mapper = [[LoginResponseJsonMapper alloc] init];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		NSError *parseError = [mapper parseWithJSONObject:jsonDict];
		if (!parseError) {
			LoginResponse *response = mapper.response;
			if (![StringUtils isEmpty:response.error]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error];
			} else if ([StringUtils isEmpty:response.user.cookie_string]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:[Vars responseException]];
			} else {
				User *user = response.user;
				user.uid = login.username;
				user.pass1 = login.password;
				[Vars appDelegate].loginUser = user;

				NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
				[userDefaults setInteger:[Vars appDelegate].loginUser.id forKey:UserDefaultsKeyUserID];
				[userDefaults setObject:[Vars appDelegate].loginUser.uid forKey:UserDefaultsKeyUserName];
				[userDefaults setObject:[Vars appDelegate].loginUser.pass1 forKey:UserDefaultsKeyUserPassword];

				NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
				[notificationCenter postNotificationName:SegueDidPerformNotification object:self.segueObject];
				[notificationCenter postNotificationName:LoginStatusDidChangeNotification object:nil];

                [AnswersManager logLoginWithMethod:@"Password" success:YES];
				[self.navigationController popViewControllerAnimated:self.popAnimated];

				if (self.destructiveBlock) {
					self.destructiveBlock();
				}
			}
		}
	}];
}

#if defined POD_OF_FBSDKCoreKit && defined POD_OF_FBSDKLoginKit

- (void)loginWithFacebook:(FacebookLogin *)facebookLogin {
	NSDictionary *requestDict = [Utility perlParamXml:[facebookLogin innerXML] action:facebookLogin.name];
	// NSLog(@"%@", requestDict);
	[Utility getXMLFromRequestWithMethod:@"GET" url:facebookLogin.address parameters:requestDict success:^(NSString *xml) {
		NSString *responseStr = xml;
		// NSLog(@"%@", responseStr);
		FacebookLoginResponseJsonMapper *mapper = [[FacebookLoginResponseJsonMapper alloc] init];
		NSDictionary *jsonDict = [Utility JSONObjectWithXMLString:responseStr objectMapping:mapper.objectMapping];
		if (![mapper parseWithJSONObject:jsonDict]) {
			FacebookLoginResponse *response = mapper.response;
			if (response.error_code > 0) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:response.error_message];
				[self facebookLogout];
			} else if (response.shouldLink) {
				[self linkOrNewAccountWithFacebook:facebookLogin];
			} else if (response.emailExisted) {
				[self linkEmailAccountWithFacebook:facebookLogin];
			} else if ([StringUtils isEmpty:response.user.cookie_string]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:[Vars responseException]];
			} else {
				[Vars appDelegate].loginUser = response.user;

				NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
				[userDefaults setInteger:[Vars appDelegate].loginUser.id forKey:UserDefaultsKeyUserID];

				NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
				[notificationCenter postNotificationName:SegueDidPerformNotification object:self.segueObject];
				[notificationCenter postNotificationName:LoginStatusDidChangeNotification object:nil];

                [AnswersManager logLoginWithMethod:@"Facebook" success:YES];
				[self.navigationController popViewControllerAnimated:self.popAnimated];

				if (self.destructiveBlock) {
					self.destructiveBlock();
				}
			}
		}
	}];
}

#endif

#if defined POD_OF_FBSDKCoreKit && defined POD_OF_FBSDKLoginKit

 #pragma mark - facebook-ios-sdk

- (void)alertFacebookError:(NSError *)error {
	NSString *alertMessage = error.userInfo[FBSDKErrorLocalizedDescriptionKey] ?: @"There was a problem logging in. Please try again later.";
	NSString *alertTitle = error.userInfo[FBSDKErrorLocalizedTitleKey] ?: @"Oops";
	[CocoaUtils showAlertWithTitle:alertTitle message:alertMessage];
}

- (void)facebookLogout {
	FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
	[loginManager logOut];
}

- (void)linkEmailAccountWithFacebook:(FacebookLogin *)facebookLogin {
	[CocoaUtils showInputBoxWithStyle:UIAlertViewStyleSecureTextInput title:IMLocalizedString(@"Information") message:[NSString stringWithFormat:@"There is already a %@ account for %@. Enter your %@ password to link Facebook with this account.", [Vars site_name], facebookLogin.userDetails[@"email"], [Vars site_name]] configurationHandler:^(NSInteger inputIndex, UITextField *textField) {
		if (inputIndex == 0) {
			textField.placeholder = IMLocalizedString(@"Password");
			textField.clearsOnBeginEditing = YES;
		}
	} cancelActionTitle:IMLocalizedString(@"Cancel") otherActionTitles:@[@"Link Account"] actionHandler:^(NSInteger buttonIndex, NSArray *textFields) {
		UITextField *textField = textFields[0];
		if (buttonIndex == 0) {
			if (textField.isFirstResponder) {
				[textField becomeFirstResponder];
			}
			if ([self validateForTextFields:@[textField] slient:YES]) {
				facebookLogin.shouldLink = YES;
				facebookLogin.username = facebookLogin.userDetails[@"email"];
				facebookLogin.password = textField.text;
				[self loginWithFacebook:facebookLogin];
			} else {
				[self linkEmailAccountWithFacebook:facebookLogin];
			}
		} else {
			[self facebookLogout];
		}
	}];
}

- (void)linkOrNewAccountWithFacebook:(FacebookLogin *)facebookLogin {
	NSString *linkAccountString = [NSString stringWithFormat:@"Link to my existing %@ account", [Vars site_name]];
	NSString *newAccountString = @"Continue with my Facebook account";
	[CocoaUtils showMessageBoxWithTitle:IMLocalizedString(@"Information") message:[NSString stringWithFormat:@"If you already have a %@ account. We recommend that you link to it now so that all your trips are in one place.", [Vars site_name]] cancelActionTitle:@"Cancel" otherActionTitles:@[linkAccountString, newAccountString] actionHandler:^(NSInteger buttonIndex) {
		if (buttonIndex == 0) {
			[self linkMyAccountWithFacebook:facebookLogin];
		} else if (buttonIndex == 1) {
			facebookLogin.shouldLink = YES;
			[self loginWithFacebook:facebookLogin];
		} else {
			[self facebookLogout];
		}
	}];
}

- (void)linkMyAccountWithFacebook:(FacebookLogin *)facebookLogin {
	[CocoaUtils showInputBoxWithStyle:UIAlertViewStyleLoginAndPasswordInput title:IMLocalizedString(@"Login") message:[NSString stringWithFormat:@"Have a %@ account?", [Vars site_name]] configurationHandler:^(NSInteger inputIndex, UITextField *textField) {
		if (inputIndex == 0) {
			textField.placeholder = IMLocalizedString(@"Email or ID");
			textField.clearButtonMode = UITextFieldViewModeWhileEditing;
		} else if (inputIndex == 1) {
			textField.placeholder = IMLocalizedString(@"Password");
			textField.clearsOnBeginEditing = YES;
		}
	} cancelActionTitle:IMLocalizedString(@"Cancel") otherActionTitles:@[IMLocalizedString(@"Link Account")] actionHandler:^(NSInteger buttonIndex, NSArray *textFields) {
		UITextField *loginInput = textFields[0];
		UITextField *passwordInput = textFields[1];
		if (buttonIndex == 0) {
			if (loginInput.isFirstResponder) {
				[loginInput becomeFirstResponder];
			}
			if (passwordInput.isFirstResponder) {
				[passwordInput becomeFirstResponder];
			}
			if ([self validateForTextFields:@[loginInput, passwordInput] slient:YES]) {
				facebookLogin.shouldLink = YES;
				facebookLogin.username = loginInput.text;
				facebookLogin.password = passwordInput.text;
				[self loginWithFacebook:facebookLogin];
			} else {
				[self linkOrNewAccountWithFacebook:facebookLogin];
			}
		} else {
			[self facebookLogout];
		}
	}];
}

#endif

#pragma mark - Private

- (BOOL)validateLogin:(BOOL)slient {
	return [self validateForTextFields:@[self.usernameField, self.passwordField] slient:slient];
}

- (BOOL)validateForTextFields:(NSArray *)textFields slient:(BOOL)slient {
	for (UITextField *textField in textFields) {
		if ([StringUtils isBlank:textField.text]) {
			if (!slient) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:[NSString stringWithFormat:IMLocalizedString(@"Please fill out %@"), textField.placeholder.lowercaseString] dismissalHandler:^{
					[textField becomeFirstResponder];
				}];
			}
			return NO;
		}
	}
	for (UITextField *textField in textFields) {
		if (![Utility canBeConvertedToUrlEncodedFromString:textField.text]) {
			if (!slient) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:IMLocalizedString(@"Please enter alphabetic characters only") dismissalHandler:^{
					[textField becomeFirstResponder];
				}];
			}
			return NO;
		}
	}
	return YES;
}

#if defined POD_OF_FBSDKCoreKit && defined POD_OF_FBSDKLoginKit

 #pragma mark - <FBSDKLoginButtonDelegate>

- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
	[CocoaUtils proxyTopMostViewController:self];
	[CocoaUtils hideBusyIndicator:self.view];
	if (error) {
		// NSLog(@"Unexpected login error: %@", error);
		[self alertFacebookError:error];
	} else if (result.isCancelled) {
	} else if ([FBSDKAccessToken currentAccessToken]) {
		[CocoaUtils showBusyIndicator:self.view];
		FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{ @"fields" : @"id,email,first_name,last_name,gender,birthday" }];
		[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
			[CocoaUtils hideBusyIndicator:self.view];
			if (error) {
				// NSLog(@"Picker loading error:%@", error);
				[self alertFacebookError:error];
				[self facebookLogout];
			} else if (!result[@"email"]) {
				[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Information") message:@"Please fill out your email address on Facebook"];
				[self facebookLogout];
			} else {
				// NSLog(@"%@", result);
				NSMutableDictionary *mutableResult = [NSMutableDictionary dictionaryWithDictionary:result];
				if (![Utility canBeConvertedToUrlEncodedFromString:mutableResult[@"first_name"]]) {
					mutableResult[@"first_name"] = [CocoaUtils normalizeUserGeneratedContentString:mutableResult[@"first_name"]];
				}
				if (![Utility canBeConvertedToUrlEncodedFromString:mutableResult[@"last_name"]]) {
					mutableResult[@"last_name"] = [CocoaUtils normalizeUserGeneratedContentString:mutableResult[@"last_name"]];
				}
				FacebookLogin *facebookLogin = [[FacebookLogin alloc] init];
				facebookLogin.tokenString = [FBSDKAccessToken currentAccessToken].tokenString;
				facebookLogin.userDetails = [NSDictionary dictionaryWithDictionary:mutableResult];
				[self loginWithFacebook:facebookLogin];
			}
		}];
	} else {
		[CocoaUtils showAlertWithTitle:IMLocalizedString(@"Error") message:[Vars responseException]];
	}
}

- (BOOL)loginButtonWillLogin:(FBSDKLoginButton *)loginButton {
	[CocoaUtils showBusyIndicator:self.view];
	return YES;
}

- (void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton {
}

#endif

#pragma mark

- (void)dealloc {
	[[Vars appDelegate] dashboard];
}

@end
