/*
******************************************************************************
* Copyright © 2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
*     http://www.eclipse.org/legal/epl-v10.html
*
******************************************************************************
*/
import { Branch } from './../model/branch';
import { Injectable, EventEmitter } from '@angular/core';
import { User } from '../model/user';
import { Status } from '../model/status';
import { BannerMessage } from '../common/banner-message';
import { Globals } from '../common/globals';
import { UserMap } from '../common/user-map';
import { JwtPayload } from '../model/jwt-payload';
import { JwtHelperService } from '@auth0/angular-jwt';
import { CostCenter } from '../model/cost-center';
import { BackendSettings } from './../model/backend-settings';
import { GridMeasure } from '../model/grid-measure';
import { UserSettings } from '../model/user-settings';
import { StatusMainFilter } from '../model/status-main-filter';
import { Territory } from '../model/territory';

@Injectable()
export class SessionContext {

    private timeoutId: any;
    public centralHttpResultCode$: EventEmitter<number> = new EventEmitter<number>();
    public settings;
    public reminderAvailable = false;
    public importFileAvailable = false;
    public filterExpanded = false;
    public userMap: UserMap = null;
    public userAuthenticated: boolean;
    public inactiveFields: Array<string> = [];
    public collapseState: boolean;
    bannerMessage: BannerMessage = new BannerMessage();
    getCurrSessionId(): string { return localStorage.getItem(Globals.LOCALSTORAGE_SESSION_ID); }
    setCurrSessionId(sid: string): void { localStorage.setItem(Globals.LOCALSTORAGE_SESSION_ID, sid); }

    initBannerMessage() {
        this.bannerMessage = new BannerMessage();
    }

    clearStorage() {
        this.initBannerMessage();
        localStorage.clear();
    }

    setGridMeasureDetail(gm: GridMeasure): void {
        localStorage.setItem(Globals.GRID_MEASURE, JSON.stringify(gm));
    }

    getGridMeasureDetail(): GridMeasure {
        const gm = localStorage.getItem(Globals.GRID_MEASURE);
        return JSON.parse(gm);
    }

    setCancelStage(flag: boolean): void {
        localStorage.setItem(Globals.CANCEL_STAGE, JSON.stringify(flag));
    }

    isInCancelPage(): boolean {
        const flag = localStorage.getItem(Globals.CANCEL_STAGE);
        return JSON.parse(flag);
    }

    getBackendsettings(): BackendSettings {
        return this.getSaveFromLocalStorage(Globals.BACKEND_SETTINGS);
    }

    setBackendsettings(settings: any): void {
        localStorage.setItem(Globals.BACKEND_SETTINGS, JSON.stringify(settings));
    }

    getCurrUser(): User {
        return this.getSaveFromLocalStorage(Globals.CURRENT_USER);
    }

    setCurrUser(usr: any): void {
        localStorage.setItem(Globals.CURRENT_USER, JSON.stringify(usr));
    }

    getAllUsers(): User[] {
        return this.getSaveFromLocalStorage(Globals.ALL_USERS);
    }

    setAllUsers(allUsr: User[]) {
        localStorage.setItem(Globals.ALL_USERS, JSON.stringify(allUsr));
    }

    setTabFilteringState(filterSearchText: any): void {
        localStorage.setItem(Globals.TAB_FILTERING_TEXT, JSON.stringify(filterSearchText));
    }

    getTabFilteringState(): any {
        const filterSearchText = localStorage.getItem(Globals.TAB_FILTERING_TEXT);
        return JSON.parse(filterSearchText);
    }

    getUserMap(): UserMap {
        if (this.userMap == null) {
            this.userMap = new UserMap(this.getAllUsers());
        }
        return this.userMap;
    }

    getSaveFromLocalStorage(key: string): any {
        const retValue = localStorage.getItem(key);
        if (!retValue) {
            console.log('WARNING: Try to access LocalStorage key [' + key + '] which is empty!');
            return null;
        }
        return JSON.parse(retValue);
    }

    setBannerMessage(bannerMessage: BannerMessage): void {
        this.bannerMessage = bannerMessage;

        if (this.timeoutId) {
            clearTimeout(this.timeoutId);
            this.timeoutId = null;
        }

        if (bannerMessage.isSetTimeout) {
            this.timeoutId = setTimeout(() => {
                this.bannerMessage.hide();
            }, Globals.TIME_TO_HIDE_MESSAGE_BANNER);
        }

    }

    setFilterExpansionState(filterExpanded: boolean): void {
        this.filterExpanded = filterExpanded;
    }

    getFilterExpansionState(): boolean {
        return this.filterExpanded;
    }

    setBranches(branches: Branch[]): void {
        localStorage.setItem(Globals.BRANCHESNAME, JSON.stringify(branches));
    }

    getBranches(): Branch[] {
        const branches = localStorage.getItem(Globals.BRANCHESNAME);
        return JSON.parse(branches);
    }

    setNetworkControlsFromSingleGridmeasures(networkControls: string[]): void {
        localStorage.setItem(Globals.NETWORKCONTROLSNAME, JSON.stringify(networkControls));
    }

    getNetworkControlsFromSingleGridmeasures(): string[] {
        const networkControls = localStorage.getItem(Globals.NETWORKCONTROLSNAME);
        return JSON.parse(networkControls);
    }

    setStatuses(statuses: Status[]): void {
        localStorage.setItem(Globals.STATUSES, JSON.stringify(statuses));
    }
    setCostCenters(costCenters: CostCenter[]): void {
        localStorage.setItem(Globals.COSTCENTERS, JSON.stringify(costCenters));
    }
    getCostCenters(): CostCenter[] {
        const costCenter = localStorage.getItem(Globals.COSTCENTERS);
        return JSON.parse(costCenter);
    }
    setEmailAddressesFromTemplates(emailAddresses: string[]): void {
        localStorage.setItem(Globals.EMAILADDRESSES_FROM_TEMPLATE, JSON.stringify(emailAddresses));
    }
    getEmailAddressesFromTemplates(): string[] {
        const emailAddresses = localStorage.getItem(Globals.EMAILADDRESSES_FROM_TEMPLATE);
        return JSON.parse(emailAddresses);
    }

    setTerritories(ter: Territory[]): void {
        localStorage.setItem(Globals.TERRITORY, JSON.stringify(ter));
    }

    getTerritories(): Territory[] {
        const ter = localStorage.getItem(Globals.TERRITORY);
        return JSON.parse(ter);
    }

    getStatuses(): Status[] {
        const statuses = localStorage.getItem(Globals.STATUSES);
        return JSON.parse(statuses);
    }
    getCostCenterById(id: number): CostCenter {
        const costCenters = this.getCostCenters();
        if (costCenters) {
            const costCenter = costCenters.filter(s => s.id === id)[0];
            if (costCenter) {
                return costCenter;
            } else {
                return null;
            }
        }
        return { id: 0, name: 'NOCOSTCENTER' };
    }
    getStatusById(id: number): Status {
        const statuses = this.getStatuses();
        if (statuses) {
            const status = statuses.filter(s => s.id === id)[0];
            if (status) {
                return status;
            } else {
                return null;
            }
        }
        return { id: 0, name: 'NOSTATUS', colorCode: 'NOCOLOR' };
    }

    getBranchById(id: number): Branch {
        const bracnh = this.getBranches();
        if (bracnh) {
            // tslint:disable-next-line:triple-equals
            const branch = bracnh.filter(s => s.id == id)[0];
            if (branch) {
                return branch;
            } else {
                return null;
            }
        }
        return { id: 0, name: 'NOBRANCHES', description: 'nobranches', colorCode: '' };
    }
    public getAccessToken(): string {
        return localStorage.getItem(Globals.ACCESS_TOKEN);
    }

    public setAccessToken(accessToken: string): void {
        localStorage.setItem(Globals.ACCESS_TOKEN, accessToken);
    }
    public getAccessTokenDecoded(): JwtPayload {
        const jwtHelper: JwtHelperService = new JwtHelperService();
        const jwtPayload: JwtPayload = new JwtPayload();
        const decoded: any = jwtHelper.decodeToken(this.getAccessToken());
        jwtPayload.name = decoded ? decoded.name : '';
        return jwtPayload || new JwtPayload();
    }

    public isUserAuthenticated(): boolean {
        return this.userAuthenticated;
    }

    public setUserAuthenticated(flag: boolean) {
        this.userAuthenticated = flag;
    }

    public getOverdueReminder(): boolean {
        return JSON.parse(localStorage.getItem(Globals.OVERDUE_REMINDERS));
    }

    public setOverdueReminder(flag: boolean) {
        localStorage.setItem(Globals.OVERDUE_REMINDERS, JSON.stringify(flag));
    }

    public getUpcomingReminder(): boolean {
        return JSON.parse(localStorage.getItem(Globals.UPCOMING_REMINDERS));
    }

    public setUpcomingReminder(flag: boolean) {
        localStorage.setItem(Globals.UPCOMING_REMINDERS, JSON.stringify(flag));
    }

    public setBellColor(): string {
        const error = this.getOverdueReminder();
        const warning = this.getUpcomingReminder();
        if (error) {
            return 'red';
        } else if (warning) {
            return '#f79e60';
        } else {
            return 'grey';
        }
    }


    public getCurrentReminders(): number[] {
        return JSON.parse(localStorage.getItem(Globals.CURRENT_REMINDERS));
    }

    public setCurrentReminders(currentReminders: number[]) {
        const tmpCurrentReminders = currentReminders ? currentReminders : [];
        localStorage.setItem(Globals.CURRENT_REMINDERS, JSON.stringify(tmpCurrentReminders));
    }

    public getExpiredReminders(): number[] {
        return JSON.parse(localStorage.getItem(Globals.EXPIRED_REMINDERS));
    }

    public setExpiredReminders(expiredReminders: number[]) {
        const tmpExpiredReminders = expiredReminders ? expiredReminders : [];
        localStorage.setItem(Globals.EXPIRED_REMINDERS, JSON.stringify(tmpExpiredReminders));
    }

    public isShorttermNotification(ind: number): boolean {
        const tmpCurrentReminders = this.getCurrentReminders();
        if (tmpCurrentReminders) {
            const status = tmpCurrentReminders.filter(s => s === ind)[0];
            if (status && status.valueOf() > 0) {
                return true;
            }
            return false;
        }
        this.setCurrentReminders([]);
        return false;
    }
    public isOverdueNotification(ind: number): boolean {
        const tmpExpiredReminders = this.getExpiredReminders();
        if (tmpExpiredReminders) {
            const status = tmpExpiredReminders.filter(s => s === ind)[0];
            if (status && status.valueOf() > 0) {
                return true;
            }
            return false;
        }
        this.setExpiredReminders([]);
        return false;
    }

    public setInactiveFieldsArray(fields: Array<string>) {
        this.inactiveFields = fields;
    }

    public getInactiveFields() {
        return this.inactiveFields;
    }

    public isReadOnlyForStatus(gm: GridMeasure) {
        const status = gm.statusId;
        if (status !== Globals.STATUS.NEW && status !== Globals.STATUS.APPLIED) {
            return true;
        }
    }


    getUserSettings(): UserSettings {
        return JSON.parse(localStorage.getItem(Globals.USER_SETTINGS));
    }

    setUserSettings(sett: any): void {
        localStorage.setItem(Globals.USER_SETTINGS, JSON.stringify(sett));
    }

    getSortingState(): any {
        return JSON.parse(localStorage.getItem(Globals.SORTING_STATE));
    }

    setSortingState(state: any): void {
        localStorage.setItem(Globals.SORTING_STATE, state);
    }

    getFilteringSearchText(): any {
        return JSON.parse(localStorage.getItem(Globals.FILTERING_SEARCH_TEXT));
    }

    setFilteringSearchText(txt: any): void {
        localStorage.setItem(Globals.FILTERING_SEARCH_TEXT, txt);
    }

    getColumnState(): any {
        return JSON.parse(localStorage.getItem(Globals.COLUMN_STATE));
    }

    setColumnState(state: any): void {
        localStorage.setItem(Globals.COLUMN_STATE, state);
    }

    getStatusMainFilter(): StatusMainFilter {
        return JSON.parse(localStorage.getItem(Globals.STATUS_MAIN_FILTER));
    }

    setStatusMainFilter(state: StatusMainFilter): void {
        localStorage.setItem(Globals.STATUS_MAIN_FILTER, JSON.stringify(state));
    }

    getFilterDirtyState(): boolean {
        return JSON.parse(localStorage.getItem(Globals.DIRTY_STATE_FILTER));
    }

    setFilterDirtyState(state: boolean): void {
        localStorage.setItem(Globals.DIRTY_STATE_FILTER, JSON.stringify(state));
    }

    isLocked(): boolean {
        return JSON.parse(localStorage.getItem(Globals.READ_ONLY_FORM));
    }

    setIsLocked(state: boolean): void {
        localStorage.setItem(Globals.READ_ONLY_FORM, JSON.stringify(state));
    }

}
