import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Observable, Observer } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ErrorMessages, FormConstants, HiddenValues, SuccessMessages } from '../utils/enums';
import { CredentialService } from './credential.service';
import { AuthenticationToken, UserCredentials } from '../authenticate/authenticate';
import { HttpURIService } from '../app.http.uri.service';
import { URIKey } from '../utils/uri-enums';
import { I18NService } from './i18n.service';
import { StorageService } from '../shared/services/storage.service';
import { ButtonManagementService } from './button-management.service';

@Injectable(
    { providedIn: 'root' }
)
export class AuthenticationService {
    showLicenseInfo: boolean = false;
    reset: boolean = false;

    public onAuthenticationComplete: BehaviorSubject<boolean> = new BehaviorSubject(<boolean>false);

    constructor(private buttonManagementService: ButtonManagementService, private httpService: HttpURIService, private router: Router, private credentialService: CredentialService, private i18nService: I18NService, private storageService: StorageService) {
    }
    authenticate(uCreds: UserCredentials): Observable<any> {
    //     const userJson = this.storageService.getItem('user');
    // if (this.storageService.getItem('user') != null) {
    //     this.i18nService.error(ErrorMessages.ALREADY_LOGGED_IN, []);
    //     return new Observable(); // empty
    // }

    this.credentialService.setPorOrgacode(HiddenValues.POR_ORGACODE);
    this.credentialService.setUserId(uCreds.userId);
    this.credentialService.setPassword(uCreds.password);
    this.storageService.setItem(FormConstants.POR_ORGACODE, HiddenValues.POR_ORGACODE);
    this.storageService.setItem(FormConstants.USER_ID, uCreds.userId);
    this.storageService.setItem(FormConstants.PASSWORD, uCreds.password);

    return this.httpService.requestPOST(URIKey.USER_LOGIN_URI, uCreds).pipe(
        tap((data: any) => {
            if (!(data instanceof HttpErrorResponse)) {
                data.authenticated = true;
                this.storageService.setItem('user', JSON.stringify(data));
                this.credentialService.setToken(data.token);
                this.credentialService.setUserType(data.role);

                if (data.user.permissions) {
                    this.storageService.setItem('permission', data.user.permissions);
                    this.credentialService.setPermission(JSON.parse(data.user.permissions));
                } else {
                    this.storageService.setItem('permission', '[]');
                    this.credentialService.setPermission([]);
                }

                this.buttonManagementService.setButtonPermissions(this.credentialService.getPermission(), this.isAdminUser());
            }
        })
    );
}

    updateCredentialsAfterPasswordChange(newPassword: string) {
    this.storageService.setItem(FormConstants.PASSWORD, newPassword);
    this.credentialService.setPassword(newPassword);
    const userStr = this.storageService.getItem('user');
    if (userStr) {
        const user = JSON.parse(userStr);
        user.authenticated = true; 
        this.storageService.setItem('user', JSON.stringify(user));
    }
}

    isAuthenticated(): boolean {
        if (this.storageService && this.storageService.getItem('user') != null) {
            let cachedUser = JSON.parse(this.storageService.getItem('user') || '{}');
            return cachedUser.authenticated;
        }
        return false;
    }

    isAdminUser(){
        if (this.storageService && this.storageService.getItem('user') != null) {
            let cachedUser = JSON.parse(this.storageService.getItem('user') || '{}');
            return cachedUser.user.role === HiddenValues.SUPER_ADMIN;
        }
        return false;
    }

    refreshToken() {
        let uCreds: UserCredentials = { porOrgacode: this.credentialService.getPorOrgacode(), userId: this.credentialService.getUserId(), password: this.credentialService.getPassword(), token: this.credentialService.getToken() };
        return this.httpService.requestPOST<AuthenticationToken>(URIKey.USER_REFRESH_TOKEN, uCreds).pipe(
            tap(response => {
                this.credentialService.setToken(response.token);
                let cachedUser = JSON.parse(this.storageService.getItem('user') || '{}');
                cachedUser.token = response.token;
                this.storageService.setItem('user', JSON.stringify(cachedUser));
            })
        );
    }

    logout() {
        let defaultPermission: string = this.storageService.getItem("defaultPermission") || "{}";
        this.storageService.clear();
        this.storageService.setItem("defaultPermission", defaultPermission)
        this.credentialService.resetService();
        this.router.navigate(['/login']);
        
    }

} 