import { Injectable } from '@angular/core';
import { HttpService } from '../http/http.service';
import { Router } from '@angular/router';
import { from, Observable } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { UserRole, User } from '@lib/typings/ce';

@Injectable({
	providedIn: 'root'
})
export class AuthService {
	protected hasCheckAuth = false;
	protected user: User | null = null;

	constructor(
		protected httpService: HttpService,
		protected router: Router
	) {}

	async login(username: string, password: string) {
		try {
			await this.httpService.login({ username, password });
			await this.getAuthenticatedUser(true);
		} catch (err) {
			const error = err as HttpErrorResponse;
			console.error(error.error.message || error.error);
			throw error;
		}
	}

	refreshToken(): Observable<{ message: string }> {
		return from(this.httpService.refreshToken());
	}

	async logout(redirectTo?: string) {
		try {
			await this.httpService.logout();
			this.user = null;

			if (redirectTo) {
				this.router.navigate([redirectTo]);
			}
		} catch (error) {
			console.error((error as HttpErrorResponse).error.message);
		}
	}

	async isUserAuthenticated(): Promise<boolean> {
		await this.getAuthenticatedUser();
		return !!this.user;
	}

	async getUsername(): Promise<string | undefined> {
		await this.getAuthenticatedUser();
		return this.user?.username;
	}

	async getUserRole(): Promise<UserRole | undefined> {
		await this.getAuthenticatedUser();
		return this.user?.role;
	}

	private async getAuthenticatedUser(force = false) {
		if (force || (!this.user && !this.hasCheckAuth)) {
			try {
				const user = await this.httpService.getProfile();
				this.user = user;
			} catch (error) {
				this.user = null;
			}
			
			this.hasCheckAuth = true;
		}
	}
}
