/* Copyright CloudLinux Zug GmbH 2010-2017 All Rights Reserved
 *
 * Licensed under CLOUD LINUX LICENSE AGREEMENT
 * http://cloudlinux.com/docs/LICENSE.TXT
 */

import { Component, ElementRef } from '@angular/core';
import { BaseComponent } from './base_component';
import { AppState } from '../app.service';
import { Field, Row } from './row';
import { Message } from '../model/message';
import { KEY_CONFIRMATION_MESSAGE } from '../services/constants';
import { TranslateClass } from './pipes/translate';
import { FormatedValue, NotificationMessageData } from './types';
import { Package } from '../model/package';
import { LoaderSelector } from './loader';

declare var jQuery: any;


@Component({
    selector: 'modal_limits',
    template: require('./../../templates/modal_limits.html'),
    styles: [
        require('../../styles/modal_limits.less'),
    ]
})
export class ModalLimits extends BaseComponent {

    static modalLimitsFieldOrder: Array<string> = [
        'id',
        'username',
        'package',
        'limits_cpu_all',
        'limits_vmem',
        'limits_pmem',
        'limits_io_all',
        'limits_iops',
        'limits_ep',
        'limits_nproc',
        'limits_inodes_soft',
        'limits_inodes_hard'
    ];

    userType: string;
    row: Row;
    columns: Array<string>;
    protected provider: any;

    protected resellerWarningMessage: Array<NotificationMessageData>;
    type: string;
    changing_status: boolean = false;
    changing_type: string;
    is_cagefs: boolean = false;
    is_mysql: boolean = false;
    notSavedStatusOfLimits: boolean = false;
    loaderSelector = new LoaderSelector('#modal_limits .modal-dialog', true);
    preparedLines: Field[] = [];
    hasLimits: boolean;
    currentConfirmationMessage: Message;
    translate: TranslateClass = new TranslateClass();

    limits_labels = {
        'speed': 'SPEED',
        'mysql-cpu': 'SPEED MYSQL',
        'maxEntryProcs': 'EP',
        'io': 'IO',
        'mysql-io': 'MySQL IO',
        'iops': 'IOPS',
        'nproc': 'NPROC',
        'pmem': 'PMEM',
        'vmem': 'VMEM',
        'inodes_soft': 'INODES soft',
        'inodes_hard': 'INODES hard',
    };

    /**
     * String representation for boolean property "notSavedStatusOfLimits"
     * @returns {string}
     */
    get stringNSSOL(): string { //
        return this.notSavedStatusOfLimits ? 'enable' : 'disable';
    }

    public getConfirmationMessage(type): Message {
        const context = {
            'default': {},
            'switchLimits': {'status': this.stringNSSOL}
        };
        let curType = context.hasOwnProperty(type) ? type : 'default';
        return new Message(KEY_CONFIRMATION_MESSAGE + '.' + curType, context[curType]);
    }

    constructor(
        public appState: AppState,
        public elementRef: ElementRef
    ) {
        super();
        this.userType = this.appState.get('userType');
    }

    loadEditing(row: Row, provider) {
        this.row = row;
        this.type = 'package';
        this.resellerWarningMessage = [{
            title: 'WARNING.PackageOfResellerManageWarning.title',
            description: 'WARNING.PackageOfResellerManageWarning.description'
        }];
        this.columns = Object.keys(row.cells);
        this.provider = provider;
        if (row.hasOwnProperty('enabledLimits')) {
            this.notSavedStatusOfLimits = row['enabledLimits'];
        }
        this.currentConfirmationMessage = this.getConfirmationMessage('default');
        this.prepareLines();
    }

    prepareLines () {
        this.preparedLines = [];
        this.columns = ModalLimits.modalLimitsFieldOrder.filter(item =>
            this.columns.indexOf(item) !== -1
        );
        let isUnderReseller = this.row['isUnderReseller'];
        for (let column of this.columns) {
            this.row.cells[column].lines.forEach((line: any, i) => {
                if (line.editing && (!isUnderReseller || line.isProtected)) {
                    line.column = column;
                    line.number = i;
                    line.stringValue = line.value.hasOwnProperty('rawValue') ?
                        line.value.value : line.value;
                    this.preparedLines.push(line);
                }
            });
        }
        this.hasLimits = !!this.preparedLines.length;
    }

    resetAllErrors() {
        this.row['hasError'] = false;
        for (let column of this.columns) {
            this.row.cells[column].lines.forEach((line, i) => {
                if (line.editing) {
                    line.resetErrors();
                }
            });
        }
    }

    show() {
        jQuery(this.elementRef.nativeElement).find('.modal').modal('show');
    }

    close() {
        this.changing_status = false;
        this.resetAllErrors();
        if (this.provider.closeEdit) {
          this.provider.closeEdit(this.row);
        }
        this.row = null;
    }

    save(){
        this.preparedLines.forEach(line => {
            if (line.value.hasOwnProperty('rawValue')) {
                (<FormatedValue>line.value).value = line.stringValue;
            } else {
                line.value = line.stringValue;
            }
        });

        this.provider.save(this.row);
    }

    changing (type) {
        this.changing_status = true;
        this.changing_type = type;
        this.currentConfirmationMessage = this.getConfirmationMessage(type);
    }

    save_changing() {
        this.changing_status = false;
        this.save();
    }

    cancel_changing(){
        let changeTypeMap = {
            cagefs: () => this.is_cagefs = !this.is_cagefs,
            mysql: () => this.is_mysql = !this.is_mysql,
            switchLimits: () => this.notSavedStatusOfLimits = !this.notSavedStatusOfLimits
        };
        if (!!changeTypeMap[this.changing_type]) {
            changeTypeMap[this.changing_type]();
        }
        this.changing_status = false;
    }

    validate(column, lineNumber){
        (<Package>this.row).validate(column, lineNumber);
        let line = this.row.cells[column].lines[lineNumber];
        let $element = jQuery(`[data-line-number=${lineNumber}] [data-colname=${column}]`);
        if (this.row.hasError) {
            $element.attr('data-original-title', line.tooltipTextError)
                    .tooltip('show');
        } else {
            if (line.tooltipText) {
                $element.attr('data-original-title',
                  this.translate.transform(line.tooltipText)).tooltip('show');
            } else {
                $element.tooltip('destroy');
            }
        }
    }

    ngAfterViewInit() {
        jQuery('#modal_limits').on('hidden.bs.modal', () => {
            this.close();
        });
    }
}
