/**
******************************************************************************
* Copyright © 2017-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 { Injectable, EventEmitter } from '@angular/core';
import { JwtHelper } from 'angular2-jwt';
import { User } from '../model/user';
import { Branch } from '../model/branch';
import { GridTerritory } from '../model/gridterritory';
import { Status } from '../model/status';
import { GlobalSearchFilter } from '../model/global-search-filter';
import { Notification } from '../model/notification';
import { BannerMessage } from '../common/banner-message';
import { BannerMessageStatusEn } from '../common/enums';
import { Globals } from '../common/globals';
import { FilterMatrix } from '../model/controller-model/filter-matrix';
import { DateRange } from '../model/date-range';
import { NotificationHistoryExpansionState } from '../model/notificationhistoryexpansionstate';
import { SortingState } from '../model/sorting-state';
import { JwtPayload } from '../model/jwt-payload';
import { UserMap } from '../common/user-map';
import { UserSettings } from 'app/model/user-settings';
import { Priority } from 'app/model/priority';

@Injectable()
export class SessionContext {
    public centralHttpResultCode$: EventEmitter<number> = new EventEmitter<number>();
    public settings;
    private currUser: User = null;
    private statuses: Status[];
    private branches: Branch[];
    private gridTerritories: GridTerritory[];
    private globalSearchFilter: GlobalSearchFilter;
    public reminderAvailable = false;
    public importFileAvailable = false;
    public filterExpanded = false;
    private notificationHistoryExpansionStates: NotificationHistoryExpansionState[];
    public sortingState: SortingState;
    public userMap: UserMap = null;


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

    getCollapseState(type: string): boolean {
        const colapseState = localStorage.getItem(type);
        return JSON.parse(colapseState);
    }

    setCollapseState(colapseState: boolean, type: string): void {
        localStorage.setItem(type, JSON.stringify(colapseState));
    }

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

    getUsersSettings(): UserSettings {
        return this.getSaveFromLocalStorage(Globals.USER_SETTINGS);
    }

    setUsersSettings(userSettings: UserSettings) {
        localStorage.setItem(Globals.USER_SETTINGS, JSON.stringify(userSettings, this.replacer));
    }

    setBannerMessage(bannerMessageStatus: BannerMessageStatusEn, message: string,
        isActive: true): void {
        this.bannerMessage.isActive = isActive;
        this.bannerMessage.status = bannerMessageStatus;
        this.bannerMessage.text = message;
    }

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

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

    setGridTerritories(gridTerritories: GridTerritory[]): void {
        localStorage.setItem(Globals.GRID_TERRITORIES, JSON.stringify(gridTerritories));
    }

    getGridTerritories(): GridTerritory[] {
        const gridTerritories = localStorage.getItem(Globals.GRID_TERRITORIES);
        return JSON.parse(gridTerritories);
    }

    setfilterMatrix(filterMatrix: FilterMatrix): void {
        localStorage.setItem(Globals.FILTER_MATRIX, JSON.stringify(filterMatrix));
    }

    getfilterMatrix(): FilterMatrix {
        const filterMatrix = localStorage.getItem(Globals.FILTER_MATRIX);
        return JSON.parse(filterMatrix);
    }

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

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

    setNotificationHistoryExpansionStates(notificationHistoryExpansionStates: NotificationHistoryExpansionState[]): void {
        localStorage.setItem(Globals.NOTIFICATION_HISTORY_EXPANSION_STATES, JSON.stringify(notificationHistoryExpansionStates));
    }

    getNotificationHistoryExpansionStates(): NotificationHistoryExpansionState[] {
        const notificationHistoryExpansionStates = localStorage.getItem(Globals.NOTIFICATION_HISTORY_EXPANSION_STATES);
        if (notificationHistoryExpansionStates == null) {
            this.notificationHistoryExpansionStates = new Array<NotificationHistoryExpansionState>();
            return this.notificationHistoryExpansionStates;
        } else {
            return JSON.parse(notificationHistoryExpansionStates);
        }

    }

    getNotificationHistoryExpansionStateById(id: number): boolean {
        this.notificationHistoryExpansionStates = this.getNotificationHistoryExpansionStates();
        if (this.notificationHistoryExpansionStates) {
            const notificationHistoryExpansionState = this.notificationHistoryExpansionStates
                .filter(s => (s.incidentId === id) && (s.historyOpen === true))[0];

            if (notificationHistoryExpansionState) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    setNotificationHistoryExpansionStateById(id: number, newState: boolean): void {
        this.notificationHistoryExpansionStates = this.getNotificationHistoryExpansionStates();
        const currentNotificationHistoryState = this.notificationHistoryExpansionStates.filter(item => item.incidentId === id)[0];
        if (currentNotificationHistoryState) {
            currentNotificationHistoryState.historyOpen = newState;
        } else {
            const newNotificationHistoryExpansionState = new NotificationHistoryExpansionState();
            newNotificationHistoryExpansionState.incidentId = id;
            newNotificationHistoryExpansionState.historyOpen = newState;
            this.notificationHistoryExpansionStates.push(newNotificationHistoryExpansionState);
        }
        this.setNotificationHistoryExpansionStates(this.notificationHistoryExpansionStates);
    }

    setDateRange(dateRange: DateRange, type: string): void {
        localStorage.setItem(type, JSON.stringify(dateRange));
    }

    getDateRange(type: string): DateRange {
        const dateRange = localStorage.getItem(type);
        return JSON.parse(dateRange);
    }

    setGlobalSearchFilter(globalSearchFilter: GlobalSearchFilter): void {
        localStorage.setItem(Globals.SEARCHOBJECT, JSON.stringify(globalSearchFilter));
    }

    getGlobalSearchFilter(): GlobalSearchFilter {
        const globalSearchFilter = localStorage.getItem(Globals.SEARCHOBJECT);

        if (globalSearchFilter == null) {
            this.setInitGlobalSearchFilterValues();
            return this.globalSearchFilter;
        } else {
            return JSON.parse(globalSearchFilter);
        }
    }

    setStatuses(statuses: Status[]): void {
        localStorage.setItem(Globals.STATUSES, JSON.stringify(statuses));
    }

    getStatuses(): Status[] {
        const statuses = localStorage.getItem(Globals.STATUSES);
        return JSON.parse(statuses);
    }

    setPriorities(priority: Priority[]): void {
        localStorage.setItem(Globals.PRIORITIES, JSON.stringify(priority));
    }

    getPriorities(): Priority[] {
        const priorities = localStorage.getItem(Globals.PRIORITIES);
        return JSON.parse(priorities);
    }

    getPrioById(id: number): Priority {
        const priorities = this.getPriorities();        
        if (priorities) {
            const priority = priorities.filter(s => s.id === id)[0];
            if (priority) {
                return priority;
            } 
        }
        return null;
    }

    getPrioImagePathById(id: number): string{
        const priority = this.getPrioById(id);
        if (priority) {

        }
        return "";
    }

    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' };
    }

    getBrancheById(id: number): Branch {
        const branches = this.getBranches();
        if (branches) {
            const branch = branches.filter(s => s.id === id)[0];
            if (branch) {
                return branch;
            } else {
                return null;
            }
        }
        return { id: 0, name: 'NOBRANCH', description: '-' };
    }

    getBranchClassById(fkRefBranch: number): string {
        const className = '';
        const branch = this.getBrancheById(fkRefBranch);

        switch (branch ? branch.name : '') {
            case Globals.BRANCHES.power:
                return 'power';
            case Globals.BRANCHES.gas:
                return 'gas';
            case Globals.BRANCHES.heating:
                return 'heating';
            case Globals.BRANCHES.water:
                return 'water';
            case Globals.BRANCHES.cfm:
                return 'cfm';
            default:
                break;
        }
        return '';
    }

    getBranchClassByName(branchName: string): string {

        switch (branchName) {
            case Globals.BRANCHES.power:
                return 'power';
            case Globals.BRANCHES.gas:
                return 'gas';
            case Globals.BRANCHES.heating:
                return 'heating';
            case Globals.BRANCHES.water:
                return 'water';
            case Globals.BRANCHES.cfm:
                return 'cfm';
            default:
                break;
        }
        return '';
    }

    getGridTerritoryById(id: number): GridTerritory {
        const gridTerritories = this.getGridTerritories();
        if (gridTerritories) {
            const gridTerritory = gridTerritories.filter(s => s.id === id)[0];
            if (gridTerritory) {
                return gridTerritory;
            } else {
                return null;
            }
        }
        return { id: 0, name: 'NOGRIDTERRITORY', description: '-', fkRefMaster: 0 };
    }

    getMasterGridTerritories(): GridTerritory[] {
        const gridTerritories = this.getGridTerritories();
        if (gridTerritories) {
            return gridTerritories.filter(g => g.id === g.fkRefMaster);
        }
        return null;
    }

    public isReminderAvailable(): boolean {
        return this.reminderAvailable;
    }

    public setReminderAvailable(newStatus: boolean) {
        this.reminderAvailable = newStatus;
    }

    public isImportFileAvailable(): boolean {
        return this.importFileAvailable;
    }

    public setImportFileAvailable(newStatus: boolean) {
        this.importFileAvailable = newStatus;
    }

    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: JwtHelper = new JwtHelper();
        const jwtPayload: JwtPayload = new JwtPayload();
        if (!this.getAccessToken()) return jwtPayload;
        const decoded: any = jwtHelper.decodeToken(this.getAccessToken());
        jwtPayload.name = decoded.name;
        return jwtPayload;
    }

    setInitGlobalSearchFilterValues() {
        this.globalSearchFilter = new GlobalSearchFilter;
        this.globalSearchFilter.searchString = '';
        this.globalSearchFilter.responsibilityForwarding = '';
        this.globalSearchFilter.statusOpenSelection = true;
        this.globalSearchFilter.statusInWorkSelection = true;
        this.globalSearchFilter.statusDoneSelection = true;
        this.globalSearchFilter.statusClosedSelection = true;
        this.globalSearchFilter.fkRefBranch = -1;
        this.globalSearchFilter.fkRefGridTerritory = -1;
        this.globalSearchFilter.fkRefNotificationPriority = -1;
        this.globalSearchFilter.fastSearchSelected = true;
        localStorage.setItem(Globals.SEARCHOBJECT, JSON.stringify(this.globalSearchFilter));
    }

    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, this.reviver);
    }

    replacer(key, value) {
        const originalObject = this[key];
        if(originalObject instanceof Map) {
          return {
            dataType: 'Map',
            value: Array.from(originalObject.entries()), // or with spread: value: [...originalObject]
          };
        } else {
          return value;
        }
    }

    reviver(key, value) {
        if(typeof value === 'object' && value !== null) {
          if (value.dataType === 'Map') {
            return new Map(value.value);
          }
        }
        return value;
    }
}
