/*
 *  Copyright (C) 2015-2018 Savoir-faire Linux Inc.
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *  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 "AccRingGeneralVC.h"

//cocoa
#import <Quartz/Quartz.h>


//Qt
#import <QSize>
#import <QtMacExtras/qmacfunctions.h>
#import <QPixmap>

//LRC
#import <api/lrc.h>
#import <api/newaccountmodel.h>
#import <api/newdevicemodel.h>
#import <interfaces/pixmapmanipulatori.h>
#import <globalinstances.h>

#import "RegisterNameWC.h"
#import "RestoreAccountWC.h"
#import "BackupAccountWC.h"
#import "views/NSColor+RingTheme.h"
#import "views/NSImage+Extensions.h"
#import "views/HoverTableRowView.h"
#import "ExportPasswordWC.h"
#import "utils.h"

@interface AccRingGeneralVC ()

@property (unsafe_unretained) IBOutlet NSTextField *displayNameField;
@property (unsafe_unretained) IBOutlet NSTextField *ringIDField;
@property (unsafe_unretained) IBOutlet NSTextField *registeredNameField;
@property (unsafe_unretained) IBOutlet NSButton *registerNameButton;
@property (unsafe_unretained) IBOutlet NSButton* photoView;
@property (unsafe_unretained) IBOutlet NSButton* passwordButton;
@property (unsafe_unretained) IBOutlet NSButton* removeAccountButton;
@property (unsafe_unretained) IBOutlet NSImageView* addProfilePhotoImage;
@property (unsafe_unretained) IBOutlet NSTableView* devicesTableView;
@property (unsafe_unretained) IBOutlet NSTableView* blockedContactsTableView;
@property (assign) IBOutlet NSLayoutConstraint* buttonRegisterWidthConstraint;
@property (assign) IBOutlet NSLayoutConstraint* bannedContactHeightConstraint;
@property (assign) IBOutlet NSLayoutConstraint* advancedButtonMarginConstraint;


@property AbstractLoadingWC* accountModal;
@property PasswordChangeWC* passwordModal;
@property std::string selectedAccountID;

@end

@implementation AccRingGeneralVC

QMetaObject::Connection deviceAddedSignal;
QMetaObject::Connection deviceRevokedSignal;
QMetaObject::Connection deviceUpdatedSignal;
QMetaObject::Connection contactBlockedSignal;
QMetaObject::Connection bannedContactsChangedSignal;


@synthesize displayNameField;
@synthesize ringIDField;
@synthesize registeredNameField;
@synthesize photoView;
@synthesize addProfilePhotoImage;
@synthesize accountModel;
@synthesize registerNameButton, passwordButton, removeAccountButton;
@synthesize buttonRegisterWidthConstraint;
@synthesize accountModal;
@synthesize delegate;
@synthesize devicesTableView;
@synthesize blockedContactsTableView;


typedef NS_ENUM(NSInteger, TagViews) {
    DISPLAYNAME = 100,
    DEVICE_NAME_TAG = 200,
    DEVICE_ID_TAG = 300,
    DEVICE_EDIT_TAG = 400,
    DEVICE_REVOKE_TAG = 500,
    BANNED_CONTACT_NAME_TAG = 600,
    BANNED_CONTACT_ID_TAG = 700,
    UNBLOCK_CONTACT_TAG = 800
};

-(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)awakeFromNib
{
    [super awakeFromNib];
    [photoView setBordered:YES];
    [addProfilePhotoImage setWantsLayer: YES];
    devicesTableView.delegate = self;
    devicesTableView.dataSource = self;
    blockedContactsTableView.delegate = self;
    blockedContactsTableView.dataSource= self;
    [[self view] setAutoresizingMask: NSViewMinXMargin | NSViewMaxXMargin | NSViewHeightSizable];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self updateView];
}

- (void) setSelectedAccount:(std::string) account {
    self.selectedAccountID = account;
    [self connectSignals];
    [self updateView];
    [self hideBannedContacts];
}

-(void) updateView {
    const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
    QByteArray ba = QByteArray::fromStdString(account.profileInfo.avatar);

    QVariant photo = GlobalInstances::pixmapManipulator().personPhoto(ba, nil);
    if(QtMac::toNSImage(qvariant_cast<QPixmap>(photo))) {
        [photoView setBordered:NO];
        NSImage *image = QtMac::toNSImage(qvariant_cast<QPixmap>(photo));
        CGFloat newSize = MIN(image.size.height, image.size.width);
        image = [image cropImageToSize:CGSizeMake(newSize, newSize)];
        [photoView setImage: [image roundCorners: image.size.height * 0.5]];
        [addProfilePhotoImage setHidden:YES];
    } else {
        [photoView setImage:nil];
        [photoView setBordered:YES];
        [addProfilePhotoImage setHidden:NO];
    }
    NSString* displayName = @(account.profileInfo.alias.c_str());
    [displayNameField setStringValue:displayName];
    [ringIDField setStringValue:@(account.profileInfo.uri.c_str())];
    if(account.registeredName.empty()) {
        [registerNameButton setHidden:NO];
        buttonRegisterWidthConstraint.constant = 260.0;
    } else {
        buttonRegisterWidthConstraint.constant = 0.0;
        [registerNameButton setHidden:YES];
    }

    [registeredNameField setStringValue:@(account.registeredName.c_str())];

    lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
    [passwordButton setTitle:accountProperties.archiveHasPassword ? @"Change password" : @"Create password"];
    self.accountEnabled = account.enabled;

    NSMutableAttributedString *colorTitle = [[NSMutableAttributedString alloc] initWithAttributedString:[removeAccountButton attributedTitle]];
    NSRange titleRange = NSMakeRange(0, [colorTitle length]);
    [colorTitle addAttribute:NSForegroundColorAttributeName value:[NSColor errorColor] range:titleRange];
    [removeAccountButton setAttributedTitle:colorTitle];
    [devicesTableView reloadData];
    [blockedContactsTableView reloadData];
}

-(void) connectSignals {
    QObject::disconnect(deviceAddedSignal);
    QObject::disconnect(deviceRevokedSignal);
    QObject::disconnect(deviceUpdatedSignal);
    QObject::disconnect(bannedContactsChangedSignal);
    deviceAddedSignal = QObject::connect(&*(self.accountModel->getAccountInfo(self.selectedAccountID)).deviceModel,
                                         &lrc::api::NewDeviceModel::deviceAdded,
                                         [self] (const std::string &id) {
                                             [devicesTableView reloadData];
                                         });
    deviceRevokedSignal = QObject::connect(&*(self.accountModel->getAccountInfo(self.selectedAccountID)).deviceModel,
                                           &lrc::api::NewDeviceModel::deviceRevoked,
                                           [self] (const std::string &id, const lrc::api::NewDeviceModel::Status status) {
                                               switch (status) {
                                                   case lrc::api::NewDeviceModel::Status::SUCCESS:
                                                       [devicesTableView reloadData];
                                                       break;
                                                   case lrc::api::NewDeviceModel::Status::WRONG_PASSWORD:
                                                       [self showAlertWithTitle: @"" andText: @"Device revocation failed with error: Wrong password"];
                                                       break;
                                                   case lrc::api::NewDeviceModel::Status::UNKNOWN_DEVICE:
                                                       [self showAlertWithTitle: @"" andText: @"Device revocation failed with error: Unknown device"];
                                                       break;
                                               }
                                           });
    deviceUpdatedSignal = QObject::connect(&*(self.accountModel->getAccountInfo(self.selectedAccountID)).deviceModel,
                                           &lrc::api::NewDeviceModel::deviceUpdated,
                                           [self] (const std::string &id) {
                                               [devicesTableView reloadData];
                                           });
    bannedContactsChangedSignal = QObject::connect(&*(self.accountModel->getAccountInfo(self.selectedAccountID)).contactModel,
                                                   &lrc::api::ContactModel::bannedStatusChanged,
                                                   [self] (const std::string &contactUri, bool banned) {
                                                       [blockedContactsTableView reloadData];
                                                   });
}

-(void) showAlertWithTitle: (NSString *) title andText: (NSString *)text {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert addButtonWithTitle:@"OK"];
    [alert setMessageText:title];
    [alert setInformativeText:text];
    [alert runModal];
}

- (void)pictureTakerDidEnd:(IKPictureTaker *) picker
                returnCode:(NSInteger) code
               contextInfo:(void*) contextInfo
{
    if (auto outputImage = [picker outputImage]) {
        auto image = [picker inputImage];
        CGFloat newSize = MIN(image.size.height, image.size.width);
        outputImage = [outputImage cropImageToSize:CGSizeMake(newSize, newSize)];
        [photoView setImage: [outputImage roundCorners: outputImage.size.height * 0.5]];
        [photoView setBordered:NO];
        [addProfilePhotoImage setHidden:YES];
        auto imageToBytes = QByteArray::fromNSData([outputImage TIFFRepresentation]).toBase64();
        std::string imageToString = std::string(imageToBytes.constData(), imageToBytes.length());
        self.accountModel->setAvatar(self.selectedAccountID, imageToString);
    } else if(!photoView.image) {
        [photoView setBordered:YES];
        [addProfilePhotoImage setHidden:NO];
    }
}

#pragma mark - RegisterNameDelegate methods

- (void) didRegisterName:(NSString *) name withSuccess:(BOOL) success
{
    [self.accountModal close];
    if(!success) {
        return;
    }

    if(name.length == 0) {
        return;
    }
    buttonRegisterWidthConstraint.constant = 0.0;
    [registerNameButton setHidden:YES];
    [registeredNameField setStringValue:name];
}

#pragma mark - NSTextFieldDelegate delegate methods

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

    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    self.accountModel->setAlias(self.selectedAccountID, [displayName UTF8String]);
    lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
    self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}

#pragma mark - NSTableViewDataSource methods

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
    if(tableView == devicesTableView) {
        return self.accountModel->getAccountInfo(self.selectedAccountID).deviceModel->getAllDevices().size();
    } else if (tableView == blockedContactsTableView){
        return self.accountModel->getAccountInfo(self.selectedAccountID).contactModel->getBannedContacts().size();
    }
    return 0;
}

#pragma mark - NSTableViewDelegate methods
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    if(tableView == devicesTableView) {
        NSTableCellView* deviceView = [tableView makeViewWithIdentifier:@"TableCellDeviceItem" owner:self];
        NSTextField* nameLabel = [deviceView viewWithTag: DEVICE_NAME_TAG];
        NSTextField* idLabel = [deviceView viewWithTag: DEVICE_ID_TAG];
        NSButton* revokeButton = [deviceView viewWithTag: DEVICE_REVOKE_TAG];
        NSButton* editButton = [deviceView viewWithTag: DEVICE_EDIT_TAG];
        [editButton setAction:@selector(editDevice:)];
        [editButton setTarget:self];
        [revokeButton setAction:@selector(startDeviceRevocation:)];
        [revokeButton setTarget:self];
        auto devices = self.accountModel->getAccountInfo(self.selectedAccountID).deviceModel->getAllDevices();
        auto device = devices.begin();

        std::advance(device, row);

        auto name = device->name;
        auto deviceID = device->id;

        [nameLabel setStringValue: @(name.c_str())];
        [idLabel setStringValue: @(deviceID.c_str())];
        [revokeButton setHidden: device->isCurrent];
        [editButton setHidden: !device->isCurrent];
        return deviceView;
    } else if (tableView == blockedContactsTableView) {
        NSTableCellView* contactView = [tableView makeViewWithIdentifier:@"TableCellBannedContactItem" owner:self];
        NSTextField* nameLabel = [contactView viewWithTag: BANNED_CONTACT_NAME_TAG];
        NSTextField* idLabel = [contactView viewWithTag: BANNED_CONTACT_ID_TAG];
        NSButton* revokeButton = [contactView viewWithTag: UNBLOCK_CONTACT_TAG];
        auto contacts = self.accountModel->getAccountInfo(self.selectedAccountID).contactModel->getBannedContacts();
        auto contactID = contacts.begin();
        std::advance(contactID, row);
        [idLabel setStringValue: @(contactID->c_str())];
        auto contact = self.accountModel->getAccountInfo(self.selectedAccountID).contactModel->getContact([@(contactID->c_str()) UTF8String]);
        [nameLabel setStringValue: bestNameForContact(contact)];
        [revokeButton setAction:@selector(unblockContact:)];
        [revokeButton setTarget:self];
        return contactView;
    }
}

- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
    if(tableView == devicesTableView) {
        return tableView.rowHeight;
    } else if (tableView == blockedContactsTableView) {
        CGFloat height = self.bannedContactHeightConstraint.constant;
        if(height == 150) {
            return 52;
        } else {
            return 1;
        }
    }
}

- (NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row
{
    return [tableView makeViewWithIdentifier:@"HoverRowView" owner:nil];
}

#pragma mark - Actions

- (IBAction)editPhoto:(id)sender
{
    auto pictureTaker = [IKPictureTaker pictureTaker];

    [pictureTaker beginPictureTakerSheetForWindow:[self.view window]
                                     withDelegate:self
                                   didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
                                      contextInfo:nil];

}

- (IBAction)startExportOnRing:(id)sender
{
    ExportPasswordWC *passwordWC = [[ExportPasswordWC alloc] initWithNibName:@"ExportPasswordWindow" bundle: nil accountmodel: self.accountModel];
    passwordWC.selectedAccountID = self.selectedAccountID;
    accountModal = passwordWC;
    [self.view.window beginSheet: passwordWC.window completionHandler:nil];
}
- (IBAction)triggerAdwancedSettings: (NSButton *)sender {
    [self.delegate triggerAdvancedOptions];
}

- (IBAction)enableAccount: (NSButton *)sender {
    const auto& account = accountModel->getAccountInfo(self.selectedAccountID);
    self.accountModel->enableAccount(self.selectedAccountID, !account.enabled);
    self.accountEnabled = account.enabled;
    lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
    self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}

- (IBAction)removeAccount:(id)sender
{
    NSAlert *alert = [[NSAlert alloc] init];
    [alert addButtonWithTitle:@"OK"];
    [alert addButtonWithTitle:@"Cancel"];
    [alert setMessageText: NSLocalizedString(@"Remove account",
                                             @"Remove account alert title")];
    [alert setInformativeText:NSLocalizedString(@"By clicking \"OK\" you will remove this account on this device! This action can not be undone. Also, your registered name can be lost.",
                                                @"Remove account alert message")];

    if ([alert runModal] == NSAlertFirstButtonReturn) {
        self.accountModel->removeAccount(self.selectedAccountID);
    }
}

- (IBAction)exportAccount:(id)sender
{
    BackupAccountWC* passwordWC = [[BackupAccountWC alloc] initWithNibName:@"BackupAccountWindow" bundle: nil accountmodel: self.accountModel];
    passwordWC.delegate = self;
    [passwordWC setAllowFileSelection:NO];
    passwordWC.selectedAccountID = self.selectedAccountID;
    accountModal = passwordWC;
    [self.view.window beginSheet:passwordWC.window completionHandler:nil];
}

- (IBAction)startNameRegistration:(id)sender
{
    RegisterNameWC* registerWC = [[RegisterNameWC alloc] initWithNibName:@"RegisterNameWindow" bundle: nil accountmodel: self.accountModel];
    registerWC.delegate = self;
    registerWC.selectedAccountID = self.selectedAccountID;
    self.accountModal = registerWC;
    [self.view.window beginSheet:registerWC.window completionHandler:nil];
}
- (IBAction)changePassword:(id)sender
{
    PasswordChangeWC* passwordWC = [[PasswordChangeWC alloc] initWithNibName:@"PasswordChange" bundle: nil accountmodel: self.accountModel];
    passwordWC.selectedAccountID = self.selectedAccountID;
    passwordWC.delegate = self;
    [self.view.window beginSheet:passwordWC.window completionHandler:nil];
    self.passwordModal = passwordWC;
}

- (IBAction)showBanned: (NSButton *)sender {
    CGFloat height = self.bannedContactHeightConstraint.constant;
    NSRect frame = self.view.frame;
    if(height == 150) {
        frame.size.height =  frame.size.height - 150 - 10;
    } else {
        frame.size.height =  frame.size.height + 150 + 10;
    }
    self.view.frame = frame;
    [self.delegate updateFrame];
    CGFloat advancedHeight = self.advancedButtonMarginConstraint.constant;
    self.advancedButtonMarginConstraint.constant = (height== 2) ? 40 : 30;
    self.bannedContactHeightConstraint.constant = (height== 2) ? 150 : 2;
    [[[self.blockedContactsTableView superview] superview] setHidden:![[[self.blockedContactsTableView superview] superview] isHidden]];
    [blockedContactsTableView reloadData];
}

-(void) hideBannedContacts {
    CGFloat height = self.bannedContactHeightConstraint.constant;
    NSRect frame = self.view.frame;
    if(height == 150) {
        [self showBanned:nil];
    }
}

- (IBAction)startDeviceRevocation:(NSView*)sender
{
    NSInteger row = [devicesTableView rowForView:sender];
    if(row < 0) {
        return;
    }
    auto devices = self.accountModel->getAccountInfo(self.selectedAccountID).deviceModel->getAllDevices();
    auto device = devices.begin();
    std::advance(device, row);
    if(device == devices.end()) {
        return;
    }
    [self proceedDeviceRevokationAlert:device->id];
}

- (IBAction)unblockContact:(NSView*)sender
{
    NSInteger row = [blockedContactsTableView rowForView:sender];
    if(row < 0) {
        return;
    }
    auto contacts = self.accountModel->getAccountInfo(self.selectedAccountID).contactModel->getBannedContacts();
    auto contactID = contacts.begin();
    std::advance(contactID, row);
    if(contactID == contacts.end()) {
        return;
    }
    auto contact = self.accountModel->getAccountInfo(self.selectedAccountID).contactModel->getContact([@(contactID->c_str()) UTF8String]);
    if(!contact.isBanned) {
        return;
    }
    self.accountModel->getAccountInfo(self.selectedAccountID).contactModel->addContact(contact);
}

- (IBAction)editDevice:(NSView*)sender
{
    NSInteger row = [devicesTableView rowForView:sender];
    if(row < 0) {
        return;
    }

    NSTableCellView* deviceView = [devicesTableView viewAtColumn:0 row:row makeIfNecessary:NO];
    if(!deviceView || ![deviceView isKindOfClass:[NSTableCellView class]]) {
        return;
    }

    NSTextField* nameLabel = [deviceView viewWithTag: DEVICE_NAME_TAG];
    NSButton* editButton = [deviceView viewWithTag: DEVICE_EDIT_TAG];
    if ([nameLabel isEditable]) {
        self.accountModel->getAccountInfo(self.selectedAccountID).deviceModel->setCurrentDeviceName([nameLabel.stringValue UTF8String]);
        [nameLabel setEditable:NO];
        [self.view.window makeFirstResponder:nil];
        editButton.image = [NSImage imageNamed:NSImageNameTouchBarComposeTemplate];
        return;
    }
    [nameLabel setEditable:YES];
    [nameLabel becomeFirstResponder];
    editButton.image = [NSImage imageNamed:NSImageNameTouchBarDownloadTemplate];
}

-(void) revokeDeviceWithID: (std::string) deviceID password:(NSString *) password {
    self.accountModel->getAccountInfo(self.selectedAccountID).deviceModel->revokeDevice(deviceID, [password UTF8String]);
}

-(void) proceedDeviceRevokationAlert: (std::string) deviceID {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert addButtonWithTitle:@"OK"];
    [alert addButtonWithTitle:@"Cancel"];
    [alert setMessageText:@"Revoke Device"];
    [alert setInformativeText:@"Attention! This action could not be undone!"];
    lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
    if(accountProperties.archiveHasPassword) {
        NSSecureTextField *passwordText = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
        [passwordText setPlaceholderString:@"Enter password"];
        [alert setAccessoryView:passwordText];
        if ([alert runModal] == NSAlertFirstButtonReturn) {
            [self revokeDeviceWithID:deviceID password:[passwordText stringValue]];
        }
    } else {
        if ([alert runModal] == NSAlertFirstButtonReturn) {
            [self revokeDeviceWithID:deviceID password:@""];
        }
    }
}

#pragma mark - BackupAccountDelegate methods

-(void) didCompleteExportWithPath:(NSURL*) fileUrl
{
    [[NSWorkspace sharedWorkspace] selectFile:fileUrl.path inFileViewerRootedAtPath:@""];
}

#pragma mark - PasswordChangeDelegate

-(void) paswordCreatedWithSuccess:(BOOL) success
{
    [passwordButton setTitle: success ? @"Change password" : @"Create password"];
}

@end
