import { Injectable } from '@angular/core';

import { UserManager, UserManagerSettings, User } from 'oidc-client';
//import { JwtHelperService } from '@auth0/angular-jwt';
import decode from 'jwt-decode';
import { HttpClient } from '@angular/common/http';
import { AppConfig } from '../AppConfig/AppConfig';
import { OcBasedPermission } from './OcBasedPermission';
import { OcBasedPermissionService } from './OcBasedPermission.service';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class AuthService {
    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;
    constructor(private http: HttpClient, private ocBasePermissionService: OcBasedPermissionService) {
        this.loadingcompleted = new BehaviorSubject(false);
        this.SelectedOcChanged = new BehaviorSubject("");
    }
    load() {
        this.manager = new UserManager(getClientSettings(this.http));

        this.manager.getUser().then(user => {
            this.user = user;
            this.decodedtoken = decode(this.user.access_token);
            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();
    }

    readonly MARKER_KEY = "fjslafjlak789543758934jkfjsdkj%^&*";
    readonly SET_KEY = "lafkj^&*8230394hfslajfasl";

    InitStorageListener() {
        console.log("sessionStorage.Init");
        console.log(AppConfig);
        let rediret: string = AppConfig.settings.usermanagementurl;
        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();
                // this.manager.removeUser();
                // this.manager.clearStaleState();
                // this.logOut();
                console.log(rediret);
                window.open(rediret
                    , '_self');
            }
        });
    }

    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');
        });

    }

    getSelectedOc(): string {
        return this.selectedoc;
    }
    changeSelectedOc(oc: string) {
        this.selectedoc = oc;
        this.SelectedOcChanged.next(this.selectedoc);
    }

    getUserName(): string {
        if (this.user != null) {
            return this.user.profile.name;
        }
        else {
            return null;
        }
    }

    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[] {

        if (this.user != null) {
            let x: string[] = JSON.parse(this.decodedtoken.p);
            if (this.ocBasedPermission != null && this.ocBasedPermission.length >= 1) {
                var plist = this.ocBasedPermission.find(s => s.ocCode == this.getSelectedOc());
                for (let item of plist.permission) {
                    if (!x.includes(item)) { x.push(item); }

                }

            }
            return x;
        }
        else {
            // alert('No permision');
            return [''];
        }

    }

    isPasswordExpired(): boolean {
        let result: boolean = false;

        try {
            if (this.user != null) {
                // alert(this.decodedtoken.PasswordExpired);
                result = this.decodedtoken.PasswordExpired;
            }
        } 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) {
            return this.decodedtoken.occode;
        }
        else {
            // alert('No permision');
            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 (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();

            //       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;

    //     });

    var 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'
    };
}
