/*
 *  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>
#import <AVFoundation/AVFoundation.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];
}

- (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);

    NSData *imageData = [[NSData alloc] initWithBase64EncodedString:@(account.profileInfo.avatar.c_str()) options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSImage *image = [[NSImage alloc] initWithData:imageData];
    if(image) {
        [photoView setBordered:NO];
        [photoView setImage: [image roundCorners: 350]];
        [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
{
    //do nothing when editing canceled 
    if (code == 0) {
        return;
    }
    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];
    lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(self.selectedAccountID);
    self.accountModel->setAccountConfig(self.selectedAccountID, accountProperties);
}

#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];
    if (@available(macOS 10.14, *)) {
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
        {
            [pictureTaker setValue:0 forKey:IKPictureTakerAllowsVideoCaptureKey];
        }

        if(authStatus == AVAuthorizationStatusNotDetermined)
        {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                if(!granted){
                    [pictureTaker setValue:0 forKey:IKPictureTakerAllowsVideoCaptureKey];
                }
            }];
        }
    }
    [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] superview] setHidden:![[[[self.blockedContactsTableView superview] 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
