/*
 *  Copyright (C) 2016 Savoir-faire Linux Inc.
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

#import <Cocoa/Cocoa.h>

#import "RegisterNameWC.h"
#import "AppDelegate.h"

//LRC
#import <api/lrc.h>
#import <api/newaccountmodel.h>
#import <account.h>

@implementation RegisterNameWC
{
    __unsafe_unretained IBOutlet NSTextField* registeredNameField;
    __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
    __unsafe_unretained IBOutlet NSImageView* ivLookupResult;
    __unsafe_unretained IBOutlet NSProgressIndicator* indicatorLookupResult;

    __unsafe_unretained IBOutlet NSProgressIndicator *registrationProgress;

    QMetaObject::Connection registrationEnded;
    QMetaObject::Connection registeredNameFound;

    BOOL lookupQueued;
    NSString* usernameWaitingForLookupResult;
}

NSInteger const BLOCKCHAIN_NAME_TAG             = 2;

@synthesize accountModel;

-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(lrc::api::NewAccountModel*) accountModel
{
    if (self = [self initWithWindowNibName:nibNameOrNil])
    {
        self.accountModel= accountModel;
    }
    return self;
}

- (void)windowDidLoad
{
    [super windowDidLoad];
    auto accounts = self.accountModel->getAccountList();
    [registeredNameField setTag:BLOCKCHAIN_NAME_TAG];
    [ivLookupResult setHidden:YES];
    [indicatorLookupResult setHidden:YES];
   // self.password = @"";
    //self.registeredName = @"";
   // [registeredNameField setPlaceholderString:@"Username..."];
  //  [passwordField setPlaceholderString:@"Password..."];
}

#pragma mark - Username validation delegate methods

- (BOOL)userNameAvailable
{
    return (registeredNameField.stringValue.length > 0 && self.isUserNameAvailable);
}

- (void)showLookUpAvailable:(BOOL)available andText:(NSString *)message
{
    [ivLookupResult setImage:[NSImage imageNamed:(available?@"ic_action_accept":@"ic_action_cancel")]] ;
    [ivLookupResult setHidden:NO];
    [ivLookupResult setToolTip:message];
}

- (void)onUsernameAvailabilityChangedWithNewAvailability:(BOOL)newAvailability
{
    self.isUserNameAvailable = newAvailability;
}

- (void)hideLookupSpinner
{
    [indicatorLookupResult setHidden:YES];
}

- (void)showLookupSpinner
{
    [ivLookupResult setHidden:YES];
    [indicatorLookupResult setHidden:NO];
    [indicatorLookupResult startAnimation:nil];
}

- (BOOL)lookupUserName
{
    [self showLookupSpinner];
    QObject::disconnect(registeredNameFound);
    registeredNameFound = QObject::connect(
                                           &NameDirectory::instance(),
                                           &NameDirectory::registeredNameFound,
                                           [=] ( const Account* account, NameDirectory::LookupStatus status,  const QString& address, const QString& name) {
                                               NSLog(@"Name lookup ended");
                                               lookupQueued = NO;
                                               //If this is the username we are waiting for, we can disconnect.
                                               if (name.compare(QString::fromNSString(usernameWaitingForLookupResult)) == 0) {
                                                   QObject::disconnect(registeredNameFound);
                                               } else {
                                                   //Keep waiting...
                                                   return;
                                               }

                                               //We may now stop the spinner
                                               [self hideLookupSpinner];

                                               BOOL isAvailable = NO;
                                               NSString* message;
                                               switch(status)
                                               {
                                                   case NameDirectory::LookupStatus::SUCCESS:
                                                   {
                                                       message = NSLocalizedString(@"The entered username is not available",
                                                                                   @"Text shown to user when his username is already registered");
                                                       isAvailable = NO;
                                                       break;
                                                   }
                                                   case NameDirectory::LookupStatus::NOT_FOUND:
                                                   {
                                                       message = NSLocalizedString(@"The entered username is available",
                                                                                   @"Text shown to user when his username is available to be registered");
                                                       isAvailable = YES;
                                                       break;
                                                   }
                                                   case NameDirectory::LookupStatus::INVALID_NAME:
                                                   {
                                                       message = NSLocalizedString(@"The entered username is invalid. It must have at least 3 characters and contain only lowercase alphanumeric characters.",
                                                                                   @"Text shown to user when his username is invalid to be registered");
                                                       isAvailable = NO;
                                                       break;
                                                   }
                                                   case NameDirectory::LookupStatus::ERROR:
                                                   default:
                                                   {
                                                       message = NSLocalizedString(@"Failed to perform lookup",
                                                                                   @"Text shown to user when an error occur at registration");
                                                       isAvailable = NO;
                                                       break;
                                                   }
                                               }
                                               [self showLookUpAvailable:isAvailable andText: message];
                                               [self onUsernameAvailabilityChangedWithNewAvailability:isAvailable];
                                           }
                                           );

    //Start the lookup in a second so that the UI dosen't seem to freeze
    BOOL result = NameDirectory::instance().lookupName(nullptr, QString(), QString::fromNSString(usernameWaitingForLookupResult));
}

- (void)controlTextDidChange:(NSNotification *)notif
{
    NSTextField* textField = [notif object];
    if (textField.tag != BLOCKCHAIN_NAME_TAG) {
        return;
    }
    NSString* alias = textField.stringValue;

    [self showLookupSpinner];
    [self onUsernameAvailabilityChangedWithNewAvailability:NO];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(lookUp:) withObject:alias afterDelay:0.5];
}

- (void) lookUp:(NSString*) name
{
    if (!lookupQueued) {
        usernameWaitingForLookupResult = name;
        lookupQueued = YES;
        [self lookupUserName];
    }
}

#pragma mark - Registration process

- (IBAction)registerUsername:(id)sender
{
    [registrationProgress startAnimation:nil];
    [self showLoading];
    [self setCallback];

    self.isUserNameAvailable = self.accountModel->registerName(self.selectedAccountID, [passwordField.stringValue UTF8String], [registeredNameField.stringValue UTF8String]);
    if (!self.isUserNameAvailable) {
        NSLog(@"Could not initialize registerName operation");
        QObject::disconnect(registrationEnded);
    }
}

- (void)setCallback
{
    QObject::disconnect(registrationEnded);
    registrationEnded = QObject::connect(self.accountModel,
                                         &lrc::api::NewAccountModel::nameRegistrationEnded,
                                         [self] (const std::string& accountId, lrc::api::account::RegisterNameStatus status, const std::string& name) {
                                             if(accountId.compare(self.selectedAccountID) != 0) {
                                                 return;
                                             }
                                             switch(status)
                                             {
                                                 case lrc::api::account::RegisterNameStatus::SUCCESS: {
                                                     [self.delegate didRegisterName:  registeredNameField.stringValue withSuccess: YES];
                                                     break;
                                                 }
                                                 case lrc::api::account::RegisterNameStatus::INVALID_NAME:
                                                 case lrc::api::account::RegisterNameStatus::WRONG_PASSWORD:
                                                 case lrc::api::account::RegisterNameStatus::NETWORK_ERROR:
                                                 case lrc::api::account::RegisterNameStatus::ALREADY_TAKEN: {
                                                     [self showError];
                                                     break;
                                                 }
                                             }
                                             QObject::disconnect(registrationEnded);
                                         });
}


+ (NSSet *)keyPathsForValuesAffectingUserNameAvailableORNotBlockchain
{
    return [NSSet setWithObjects: NSStringFromSelector(@selector(isUserNameAvailable)), nil];
}


@end
