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

import { Component, ViewContainerRef, ViewChild, HostListener } from '@angular/core';
import { AppState } from '../../app/app.service';
import { BaseComponent } from '../../app/utils/base_component';
import { PingRepo } from '../../app/repository/ping_repo';
import { XHR } from '../../app/utils/xhr';
import { NotificationsService } from '../../app/services/notifiaction_service';
import { NavigationStart, Router, RouterOutlet } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { DEFAULT_LANGUAGE } from '../../app/services/constants';
import { PlatformLocation } from '@angular/common';
import { OWNER_USER } from '../../app/services/access';
import { ApplicationComponent } from '../application-component/application.component';
import { AppService } from '../app.service';
import { TranslateClass } from '../../app/utils/pipes/translate';

declare let imagePath: any;
declare const panelName: any;
declare const panelVersion: any;
declare const userName: any;
declare const userDomain: any;
declare const currentLanguage: any;

type AppMode = '' | 'create' | 'edit';

@Component({
    selector: 'lvemanager',
    template: require('./app.component.html'),
    providers: [NotificationsService, XHR, PingRepo],
    styles: [require('./app.component.less')]
})


export class App extends BaseComponent {
    @ViewChild(RouterOutlet) public routerOutlet: RouterOutlet;
    @ViewChild('tabHeader') public tabHeader: any;
    @ViewChild('tabHeaderFixed') public tabHeaderFixed: any;
    public tabs = [];
    public localeExceptions = ['pt_br'];

    public saveMode: AppMode;

    public notification_options = {
        timeOut: 5000,
        lastOnBottom: true,
        clickToClose: true,
        maxLength: 0,
        maxStack: 7,
        showProgressBar: false,
        pauseOnHover: true,
        preventDuplicates: false,
        preventLastDuplicates: 'visible',
        rtl: false,
        animate: true,
        open: false
    };

    private hasChanges: boolean = false;

    private topNavYPosition: number = 0;
    private navIsFixed: boolean = false;

    public get noNodeJSVersions() {
        return !this.hasVersions()
            ? new TranslateClass().transform('noNodeJSVersionsEnabled')
            : null;
    }

    @HostListener('window:scroll', [])
    onWindowScroll() {
        let offset = window.pageYOffset
            || document.documentElement.scrollTop
            || document.body.scrollTop
            || 0;
        this.navIsFixed = offset > this.topNavYPosition
            && /\/applications.*/gi.test(this.router.url);
        if (window.pageXOffset !== 0) {
            this.tabHeaderFixed.nativeElement.style.left = -window.pageXOffset + 'px';
        } else {
            this.tabHeaderFixed.nativeElement.style.left = 'inherit';
        }
    }

    @HostListener('window:resize', [])
    onWindowResize() {
        this.topNavYPosition = this.getElementPositionFromTop(this.tabHeader.nativeElement);
        this.onWindowScroll();
    }

    ngAfterViewInit () {
        this.topNavYPosition = this.getElementPositionFromTop(this.tabHeader.nativeElement);
    }

    constructor(
        public appState: AppState,
        public viewRef: ViewContainerRef,
        private translate: TranslateService,
        private router: Router,
        private platformLocation: PlatformLocation,
        private appService: AppService
    ) {
        super();
        this.appState.set('imagePath', imagePath);
        this.appState.set('panelName', panelName);
        this.appState.set('userType', OWNER_USER);
        this.appState.set('userName', userName);
        this.appState.set('userDomain', userDomain);
        this.appState.set('currentLanguage', currentLanguage);

        this.appState.set('historyLength', 0);

        this.setupLanguages();

        this.router.events.subscribe((val) => {
            if (val instanceof NavigationStart) {
                this.platformLocation.replaceState(
                    {page: this.appState.get('historyLength')}, '', '');
                this.appState.set('historyLength', this.appState.get('historyLength') + 1);
            }
        });
        this.tabs = this.getTabs();

        this.platformLocation.onPopState((event: any) => {
            if (event.state) {
                this.appState.set('historyLength', event.state.page - 1); // 1 - will be returned on route event
            }
        });

        this.appState.onChange.subscribe((val) => {
            this.tabs = this.getTabs();
        });
    }

    public hasVersions(): boolean {
        return this.appService.hasVersions();
    }

    getTabs() {
        let tabList = [];
        tabList.push({link: '/', altLink: '/', text: 'Web applications'});

        if (this.appState.get('createApp') === true) {
            this.saveMode = 'create';
            tabList.push({
                link: this.router.url,
                text: 'Create application',
                icon: 'add'
            });
        } else if (typeof this.appState.get('currentAppEdit') === 'string' &&
                   this.appState.get('currentAppEdit') !== '') {
            this.saveMode = 'edit';
            tabList.push({
                link: this.router.url,
                text: this.appState.get('currentAppEdit'),
                icon: 'edit'
            });
        } else {
            this.saveMode = '';
        }
        return tabList;
    }

    public get hasSaveError(): boolean {
        let conponent: ApplicationComponent =
            <ApplicationComponent><any>this.routerOutlet.component;
        return conponent.detectFormError();
    }

    public isActive(path) {
        if (['', '/'].includes(path)) return this.router.url === '/';
        return this.router.url.indexOf(path) > -1;
    }

    public newApplication() {
        this.router.navigateByUrl('/applications');
    }

    public cancelAction() {
        this.router.navigateByUrl('/');
    }

    public destroyAction() {
        let conponent: ApplicationComponent =
            <ApplicationComponent><any>this.routerOutlet.component;
        conponent.destroyAction();
    }

    public createAction() {
        let conponent: ApplicationComponent =
            <ApplicationComponent><any>this.routerOutlet.component;
        conponent.create();
    }

    public saveAction() {
        let conponent: ApplicationComponent =
            <ApplicationComponent><any>this.routerOutlet.component;
        conponent.save();
    }

    public gotoTab(link) {
        this.router.navigateByUrl(link);
    }

    private getDAPosition(element) {
        let yPosition = 0;
        while (element) {
            yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
            element = element.offsetParent;
        }
        return yPosition + window.pageYOffset;
    }

    private getElementPositionFromTop(element) {
        return this.appState.get('panelName') === 'DA'
            ? this.getDAPosition(element)
            : this.tabHeader.nativeElement.offsetTop;
    }

    private setupLanguages() {
        this.translate.addLangs([DEFAULT_LANGUAGE]);
        this.translate.setDefaultLang(DEFAULT_LANGUAGE);

        // @TODO: Remove this block and uncomment block below when all translation resources will be ready
        let languageCode = DEFAULT_LANGUAGE;
        if (currentLanguage.indexOf('-') === -1) {
            languageCode = languageCode + '-' + languageCode.toUpperCase();
        }
        this.appState.set('languageCode', languageCode);

        // let languageCode = currentLanguage || DEFAULT_LANGUAGE;
        // if (currentLanguage.indexOf('-') === -1) {
        //     languageCode = languageCode + '-' + languageCode.toUpperCase();
        // }
        // this.appState.set('languageCode', languageCode);

        // if (currentLanguage !== DEFAULT_LANGUAGE) {
        //     let language = currentLanguage.toLowerCase().replace('-', '_');
        //     if (!this.localeExceptions.includes(language)) {
        //         language = language.substr(0, 2);
        //     }
        //     this.translate.addLangs([language]);
        //     this.translate.use(language);
        // }
    }

}
