import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { UserManager, UserManagerSettings, User } from 'oidc-client';
// import { JwtHelperService } from '@auth0/angular-jwt';
import decode from 'jwt-decode';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AppConfig } from '../AppConfig/AppConfig';
import { OcBasedPermission } from './OcBasedPermission';
import { OcBasedPermissionService } from './OcBasedPermission.service';
import { BehaviorSubject } from 'rxjs';
import { SideBarMenuClass } from 'ekangularbase/src/SideBarMenu/side-bar-menu';

@Injectable()
export class AuthService {

    readonly CHANGE_OC_KEY = 'juroiu472389hjkhsf&^%*&(uewor2323';
    readonly MARKER_KEY = 'fjslafjlak789543758934jkfjsdkj%^&*';
    readonly SET_KEY = 'lafkj^&*8230394hfslajfasl';
    readonly OCCODE_KEY = 'jfaskK*&sdjfh^@KhJHGUI89K%)kems';
    readonly LASTACTIONTIME_KEY = 'jlkfaiu7235&*^(*sklafjaskl';

    private manager: UserManager;
    private user: User = null;
    private selectedocCode: string = null;
    private userPermission: string[] = [];
    // private observerStatus: string[] = [];
    private ocBasedPermission: OcBasedPermission[] = [];
    private decodedtoken: any;
    public loadingcompleted: BehaviorSubject<boolean>;
    public SelectedOcChanged: BehaviorSubject<string>;
    private selectedoc: string;

    public isRedirect = false;
    public currentUrl: string;
    public pageState: string;
    public pageName: string;
    public getEstimateEntryOnOcChange: boolean;
    public isEstimateEntryLoaded: boolean;
    public isToastDialogEnabled: boolean;
    public pageHeaderFinYear: BehaviorSubject<string>;
    public estimateEntryId: string;
    public financialYear: number;
    public financialMonthStart: number;
    public financialDesc: string;
    public financialStatus: string;
    public isEstimateEntryClosed: boolean;
    public getById: boolean;
    public isAdd: boolean;
    public previousOC: string;
    public estimateOCcode: string;
    public currentSidebarMenu: SideBarMenuClass[];
    public menuClicked: BehaviorSubject<any>;

    constructor(private http: HttpClient,
        private ocBasePermissionService: OcBasedPermissionService) {
        this.loadingcompleted = new BehaviorSubject(false);
        this.SelectedOcChanged = new BehaviorSubject('');
        this.pageHeaderFinYear = new BehaviorSubject('');
        this.menuClicked = new BehaviorSubject({previousUrl: '', currentUrl: ''});
        this.estimateEntryId = this.estimateOCcode = this.previousOC = null;
        this.getById = false;
    }

    load() {
        this.manager = new UserManager(getClientSettings(this.http));

        this.manager.getUser().then(user => {
            this.user = user;
            this.decodedtoken = decode(this.user.access_token);
            if (this.getOcCodes().length === 0) {
                console.log('no oc');
                alert('You do not have access to this OC server. Please contact system administrator. Click OK to log out.');
                this.logOut();
                return;
            }
            const c = localStorage.getItem(this.OCCODE_KEY + this.getUserName());
            if (!c) {
                let correctDefaultOc = this.getOcCodes().find(s => s === this.decodedtoken.defaultoc);

                if (!correctDefaultOc || correctDefaultOc === null) {
                    correctDefaultOc = this.getOcCodes()[0];
                }

                this.changeSelectedOc(correctDefaultOc);
            } else {
                let correctDefaultOc = this.getOcCodes().find(s => s === c);

                if (!correctDefaultOc || correctDefaultOc === null) {
                    correctDefaultOc = this.getOcCodes()[0];
                }

                this.changeSelectedOc(correctDefaultOc);
            }
            // this.changeSelectedOc(this.decodedtoken.defaultoc);
            // // this.userPermission = this.getPermissions();
            // this.getOcBasedPermissions();
            // this.userPermission = this.getPermissions();
            // this.loadingcompleted.next(true);
        }).catch(function (err) {
            console.log(err);
        });

        this.InitStorageListener();
    }

    InitStorageListener() {
        console.log('sessionStorage.Init');
        console.log(AppConfig);
        const rediret: string = AppConfig.settings.UserManagerSettings.post_logout_redirect_uri;
        console.log(rediret);
        // rediret = rediret.substring(0, rediret.length - 1) + 'ui/';
        // console.log(rediret);

        // We listen to changes on localstorage (the listener will only be fired if
        // another Browser-Tab makes changes)
        window.addEventListener('storage', (event: StorageEvent) => {
            if (event.key === this.MARKER_KEY) {
                // Another Browser-Tab removed the magic entry in localStorage (he logged out)
                // so we remove our tokens as well
                console.log('sessionStorage.clear');
                sessionStorage.clear();
                localStorage.clear();
                // this.manager.removeUser();
                // this.manager.clearStaleState();
                // this.logOut();
                console.log(rediret);
                window.open(rediret
                    , '_self');
            }
            if (event.key === this.CHANGE_OC_KEY) {
                console.log('sessionStorage.changeoc');

                this.ResetFlag();
                location.reload();
            }
        });
    }

    ResetFlag() {
        this.currentUrl = '';
        this.pageState = '';
        this.pageName = '';
        this.getById = false;
        this.isAdd = false;
        this.isRedirect = false;
    }

    getItem(key: string): string {
        return sessionStorage.getItem(key);
    }

    removeItem(key: string): void {
        sessionStorage.removeItem(key);
        if (key === this.SET_KEY) {
            // User has logged out on this Browser-Tab
            // Remove the magic entry on localStorage to tell other Browser-Tabs that they should
            // clear their session storage
            console.log('localStorage.removeItem');
            localStorage.removeItem(this.MARKER_KEY);
        }
    }

    setItem(key: string, data: string): void {
        this.removeItem(this.SET_KEY);
        sessionStorage.setItem(key, data);
        if (key === this.SET_KEY) {
            // User has logged in on this Browser-Tab
            // Set the magic entry that, when removed, fires events on other Browser-Tabs
            console.log('localStorage.setItem');
            localStorage.setItem(this.MARKER_KEY, 'true');
        }
    }

    logOut() {
        this.manager.signoutRedirect().then((user) => {
            // This will clear the OpenID access tokens that is stored in the session
            // this.manager.removeUser();
            // this.manager.clearStaleState();
            // localStorage.clear();
            this.setItem(this.SET_KEY, 'logout');
            console.log('sessionStorage.clear');
            sessionStorage.clear();
            localStorage.clear();
        });
    }

    logOutComplete() {
        console.log('logOutComplete');
        this.manager.signoutRedirect().then((user) => {
            // This will clear the OpenID access tokens that is stored in the session
            this.manager.removeUser();
            this.manager.clearStaleState();
            this.setItem(this.SET_KEY, 'logout');
            console.log('sessionStorage.clear');
            sessionStorage.clear();
            localStorage.clear();
        });
    }

    getSelectedOc(): string {
        const c = localStorage.getItem(this.OCCODE_KEY + this.getUserName());
        if (c) { return c; } else { return this.selectedoc; }
    }

    changeSelectedOc(oc: string) {
        localStorage.setItem(this.OCCODE_KEY + this.getUserName(), oc);
        this.selectedoc = oc;
        if (this.previousOC == null) {
            this.previousOC = oc;
        }
        this.SelectedOcChanged.next(this.selectedoc);
        this.setPermissions();
        // const c = localStorage.getItem(this.OCCODE_KEY + this.getUserName());
    }

    onChangeOcClick() {
        localStorage.removeItem(this.CHANGE_OC_KEY);
        localStorage.setItem(this.CHANGE_OC_KEY, 'true');
    }

    setLastActionTime() {
        localStorage.removeItem(this.LASTACTIONTIME_KEY);
        localStorage.setItem(this.LASTACTIONTIME_KEY, new Date().toString());
    }

    getLastActionTime(): string {
        return localStorage.getItem(this.LASTACTIONTIME_KEY);
    }

    getUserName(): string {
        if (this.user != null) {
            return this.user.profile.name;
        } else {
            return '';
        }
    }

    getUserId(): string {
        if (this.user != null) {
            // console.log(this.user.profile);
            return this.user.profile.sub;
        } else {
            return null;
        }
    }



    isLoggedIn(): boolean {
        return this.user != null && !this.user.expired;
    }

    // public isAuthenticated(): boolean {
    //    const token = localStorage.getItem('token');
    //    // Check whether the token is expired and return
    //    // true or false
    //    return !this.jwtHelper.isTokenExpired(token);
    // }
    getRoles(): string[] {

        if (this.user != null) {
            return this.decodedtoken.role;
        } else {
            return [''];
        }

    }

    getPermissions(): string[] {
        return this.userPermission;
    }

    setPermissions() {
        if (this.user != null && !this.isPasswordExpired()) {
            this.ocBasePermissionService.GetClaimListByModuleOc(this.getAuthorizationHeaderValue(), this.selectedoc)
                .subscribe(res => {
                    const x: string[] = res; // JSON.parse(this.decodedtoken.p);
                    //   if (this.ocBasedPermission != null && this.ocBasedPermission.length >= 1) {
                    //       const plist = this.ocBasedPermission.find(s => s.ocCode === this.getSelectedOc());
                    //       for ( const item of plist.permission) {
                    //           if (!x.includes(item)) {x.push(item); }
                    //           }
                    //       }
                    this.userPermission = x;
                    this.loadingcompleted.next(true);
                    this.GetDynamicObjListCache();
                }
                );
        } else {
            // alert('No permision');
            this.userPermission = [''];
            this.loadingcompleted.next(true);
        }
    }

    GetDynamicObjListCache() {
        try {
            if (!(AppConfig.settings.module_name === 'Ideas' || AppConfig.settings.module_name === 'Estimate')) {
                return;
            }

            this.ocBasePermissionService.GetDynamicObjListCache(this.getAuthorizationHeaderValue(),
            this.getSelectedOc()).subscribe(obj => {

            }, error => {
                console.error('cache error', error);
            }
            );
        } catch (error) {
            console.error('cache error', error);
        }
    }

    isPasswordExpired(): boolean {
        const result = false;

        try {
            if (this.user != null) {
                // alert(this.decodedtoken.PasswordExpired);
                // let a = this.decodedtoken.PasswordExpired;
                const b = this.user.profile.PasswordExpired;
                return b;
            }
        } catch (error) {
            console.log(error);
        }

        return result;
    }

    //   getObserverStatus(): string[] {

    //     if (this.user != null) {

    //     let x:string[]=  JSON.parse(this.decodedtoken.s);
    //     // alert('ss:'+JSON.stringify(x));
    //         return x;
    //     }
    //     else {
    //         // alert('No permision');
    //         return [''];
    //     }

    // }


    getOcBasedPermissions() {
        this.ocBasePermissionService.GetByUserName(this.getUserName(), this.getAuthorizationHeaderValue())
            .subscribe(res => {
                this.ocBasedPermission = res;
                // alert(JSON.stringify(this.ocBasedPermission));
            }

            );

    }

    getOcCodes(): string[] {
        if (this.user != null) {
            if (this.decodedtoken.occode && Array.isArray(this.decodedtoken.occode)) {
                return this.decodedtoken.occode;
            } else if (this.decodedtoken.occode && this.decodedtoken.occode !== null
                && this.decodedtoken.occode !== '') {
                    return [this.decodedtoken.occode];
            } else {
                return [];
            }
        } else {
            return [];
        }
    }

    getClaims(): any {

        // console.error(JSON.stringify(this.user.scopes));
        // console.error(JSON.stringify(this.user.session_state));
        // console.error(JSON.stringify(this.user.profile));
        return this.user.profile;
    }

    hasPermissions(targetpermission: string): boolean {

        if (targetpermission && this.user != null) {
            //   const tokenPayload = decode(this.user.access_token);
            //  let permissionlist:string[]= JSON.parse(tokenPayload.p);
            return this.userPermission.some(s => s.toUpperCase() === targetpermission.toUpperCase());
        } else {
            // alert('No permision');
            return false;
        }
    }

    getAuthorizationHeaderValue(): string {
        // console.log(`${this.user.token_type} ${this.user.access_token}`);
        if (this.user != null && this.user.access_token != null) { return `${this.user.token_type} ${this.user.access_token}`; } else {
            return '';

        }

    }

    getAccessToken(): string {
        // console.log(`${this.user.token_type} ${this.user.access_token}`);
        if (this.user != null) { return `${this.user.access_token}`; } else { return ''; }
    }
    startAuthentication(): Promise<void> {
        // alert('ss1');
        return this.manager.signinRedirect();
    }


    getExpiresIn(): number {
        // alert("1");
        if (this.user != null) {
            // console.log(this.user.expires_in);
            return this.user.expires_in;
        } else { return 0; }
    }

    completeAuthentication(): Promise<void> {
        //  alert("completeAuthentication");
        return this.manager.signinRedirectCallback().then(user => {
            // alert('ss');
            this.user = user;

            this.load();

            console.log(user);


            //       this.decodedtoken=decode(this.user.access_token);
            //       this.selectedoc=this.decodedtoken.defaultoc;
            //       this.userPermission = this.getPermissions();
            // this.getOcBasedPermissions();
        });
    }


}


export function getClientSettings(http: HttpClient): UserManagerSettings {

    // http.get<any>('assets/showcase/data/cars-small.json')
    //  var usersettings:any;
    //  http.get<any>('assets/config/appsettings.json')
    //   .subscribe(result => {

    //     usersettings=result.UserManagerSettings;

    //     });

    let usersettings = AppConfig.settings.UserManagerSettings;
    return {
        authority: usersettings.authority, // 'http://localhost:5000/',
        client_id: usersettings.client_id, // 'angular_spa',
        redirect_uri: usersettings.redirect_uri, // 'http://localhost:4200/#/auth-callback#',
        post_logout_redirect_uri: usersettings.post_logout_redirect_uri, // 'http://localhost:4200/',
        response_type: usersettings.response_type, // "id_token token",
        scope: usersettings.scope, // "openid profile api1",
        filterProtocolClaims: usersettings.filterProtocolClaims, // ,
        loadUserInfo: usersettings.loadUserInfo, // true,
        automaticSilentRenew: usersettings.automaticSilentRenew, // true,
        silent_redirect_uri: usersettings.silent_redirect_uri// 'http://localhost:4200/silent-refresh.html'
    };
}
