/*
 *  Copyright (C) 2019 Savoir-faire Linux Inc.
 *  Author: Kateryna Kostiuk <kateryna.kostiuk@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 "ConnectToAccManagerVC.h"
#import "utils.h"

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

@interface ConnectToAccManagerVC ()

@end

@implementation ConnectToAccManagerVC {
    __unsafe_unretained IBOutlet NSView* initialContainer;
    __unsafe_unretained IBOutlet NSView* loadingContainer;
    __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
    __unsafe_unretained IBOutlet NSView* errorContainer;

    __unsafe_unretained IBOutlet NSTextField* userNameField;
    __unsafe_unretained IBOutlet NSTextField* accountManagerField;
    __unsafe_unretained IBOutlet NSSecureTextField* passwordTextField;
}

QMetaObject::Connection accountCreatedSuccess;
QMetaObject::Connection accountNotCreated;
QString accointId;

@synthesize accountModel;

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

- (void)show
{
    self.username = userNameField.stringValue = @"";
    self.password = passwordTextField.stringValue = @"";
    self.accountManager = accountManagerField.stringValue = @"";
    [self.delegate showView:initialContainer];
}

- (void)showError
{
    [self.delegate showView:errorContainer];
}
- (void)showLoading
{
    [progressBar startAnimation:nil];
    [self.delegate showView:loadingContainer];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
}

- (IBAction)dismissViewWithError:(id)sender
{
    [self.delegate didSignInSuccess:NO accountId:""];
}

- (IBAction)startAgain:(id)sender
{
    [self show];
}


- (IBAction)signIn:(id)sender
{
    QObject::disconnect(accountCreatedSuccess);
    QObject::disconnect(accountNotCreated);
    accountCreatedSuccess = QObject::connect(self.accountModel,
                                      &lrc::api::NewAccountModel::accountAdded,
                                      [self] (const QString& accountID) {
                                          if(accountID.compare(accointId) != 0) {
                                              return;
                                          }
                                          [self.delegate didSignInSuccess:YES accountId: accointId];
                                          lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(accountID);
                                          accountProperties.Ringtone.ringtonePath = QString::fromNSString(defaultRingtonePath());
                                          self.accountModel->setAccountConfig(accountID, accountProperties);
                                          QObject::disconnect(accountCreatedSuccess);
                                          QObject::disconnect(accountNotCreated);
                                      });
    accountNotCreated = QObject::connect(self.accountModel,
                                      &lrc::api::NewAccountModel::accountRemoved,
                                      [self] (const QString& accountID) {
                                          if(accountID.compare(accointId) == 0) {
                                              [self showError];
                                          }
                                      });
    accountNotCreated = QObject::connect(self.accountModel,
                                      &lrc::api::NewAccountModel::invalidAccountDetected,
                                      [self] (const QString& accountID) {
                                          if(accountID.compare(accointId) == 0) {
                                              [self showError];
                                          }
                                      });

    [self showLoading];

    accointId = self.accountModel->connectToAccountManager(QString::fromNSString(userNameField.stringValue), QString::fromNSString(passwordTextField.stringValue), QString::fromNSString(accountManagerField.stringValue));
}

@end
