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

import {
    Component,
    ElementRef,
    EventEmitter,
    Input,
    Output,
    QueryList,
    ViewChildren
} from '@angular/core';
import { Column } from './column';
import { ColumnHeader } from './column_header';
import { Grid } from './grid';
import { AppState } from '../app.service';
import { EnvRow } from '../model/env.row';
import { ValidatorInterface } from './validator';
import { Requirements } from './row';
import { NotificationsService } from '../services/notifiaction_service';
import { UiText } from './ui-elements/ui-text/ui-text';
import { TranslateClass } from './pipes/translate';

declare let jQuery: any;


@Component({
    selector: 'env-grid',
    template: require('../../templates/environment_grid.html'),
    styles: [
        require('../../styles/grouped_grid.less'),
        require('../../styles/environment_grid.less')
    ],
})
export class EnviromentGrid extends Grid {
    _columns: any;
    @Input() rows: EnvRow[];

    @Output('action')
    actionEmitter: EventEmitter<any> = new EventEmitter();

    _headers: Array<ColumnHeader> = null;

    @ViewChildren(UiText) uiTextList: QueryList<UiText>;

    constructor(
        public appState: AppState,
        private notifictions: NotificationsService,
    ) {
        super(appState);
    }

    get headers(): Array<ColumnHeader>{
        if (!this._headers) {
            this._headers = [];
            let groups = {};
            this.columns.forEach((column: Column) => {
                let header = new ColumnHeader(column);
                this._headers.push(header);
            });
        }

        return this._headers;
    }

    get columns(): Column[] {
        return this._columns;
    }

    set columns(val: Column[]) {
        this._columns = val;
        this._headers = null;
    }

    save(row: EnvRow) {
        let nameExists = this.rows.some((item) => row.hasError);
        if (nameExists) {
            this.notifictions.error('Environment', 'Repeated environment variable name');
            return;
        }
        this.actionEmitter.emit({action: 'save', row: row});
        row.cells['name'].initialValue = row.cells['name'].value;
        row.cells['value'].initialValue = row.cells['value'].value;
        row.closeEditing();
        this.validateAll();
    }

    validateAll() {
        this.uiTextList.forEach((item) => {
           item.validator.validate(item.innerValue, null, item.elementRef, item.validatorData);
        });
    }

    cancel(row: EnvRow) {
        row.closeEditing();
        row.restoreCells();
        if (row.name === '') {
            this.rows.splice(this.rows.indexOf(row), 1);
        }
    }

    deleteRow(row: EnvRow) {
        row.closeEditing();
        this.actionEmitter.emit({action: 'delete', row: row});
    }

    envEnter(event: KeyboardEvent, row: EnvRow) {
        if ((<HTMLInputElement><any>event.target).name === 'value') {
            this.save(row);
        }
    }

    validator = () => {
        return new EnvironmentValidator(this);
    }

}


class EnvironmentValidator implements ValidatorInterface {
    public static messages = {
        'nameExists': 'Variable name already exists',
        'required': 'Required field'
    };

    hasRequirements: boolean = true;
    grid: Grid;
    error: boolean;
    translater: TranslateClass;

    private errorMessages: string[] = [];

    defineRequirements(requirements: Requirements[]) {}

    constructor (grid: Grid) {
        this.grid = grid;
        this.translater  = new TranslateClass();
    }

    public get errorMessagesAsString(): string {
        return this.errorMessages.join('. ');
    }

    public validate(value: number | string, oldValue: number | string, elementRef: ElementRef,
                    validatorData: EnvRow) {
        let element = elementRef.nativeElement;
        if ((<any>element).getElementsByTagName('input')[0].name !== 'name') {
            return [];
        }
        if (!this.grid.rows) return [];
        this.error = this.grid.rows.some(item => item.cells['name'].initialValue === value &&
                !item.cells['name'].hasChanged && item !== validatorData) || value === '';
        if (this.error) {
            if (value === '') {
                this.errorMessages = [
                    this.translater.transform(EnvironmentValidator.messages['required'])
                ];
            } else {
                this.errorMessages = [
                    this.translater.transform(EnvironmentValidator.messages['nameExists'])
                ];
            }
        } else {
            this.errorMessages = [];
        }
        let $tooltip = jQuery(element).find('input');
        validatorData.hasError = !!this.errorMessages.length;
        setTimeout(() => {
            if ($tooltip.tooltip) {
                $tooltip.tooltip(this.errorMessages.length ? 'show' : 'hide');
            }
        }, 10);
    }
}
