import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { AuthUtils } from 'app/core/auth/auth.utils';
import { UserService } from 'app/core/user/user.service';
import { catchError, Observable, of, switchMap, throwError, BehaviorSubject } from 'rxjs';
import { environment } from '@environments/environment';

@Injectable({ providedIn: 'root' })
export class AuthService {
    private _authenticated: boolean = false;
    private _httpClient = inject(HttpClient);
    private _userService = inject(UserService);
    private _currentUserRole = new BehaviorSubject<string | null>(null);

    // -----------------------------------------------------------------------------------------------------
    // @ Accessors
    // -----------------------------------------------------------------------------------------------------

    set accessToken(token: string) {
        localStorage.setItem('accessToken', token);
    }

    get accessToken(): string {
        return localStorage.getItem('accessToken') ?? '';
    }

    set userRole(role: string) {
        localStorage.setItem('userRole', role);
        this._currentUserRole.next(role);
    }

    get userRole(): string | null {
        return localStorage.getItem('userRole');
    }

    get userRole$(): Observable<string | null> {
        return this._currentUserRole.asObservable();
    }

    // -----------------------------------------------------------------------------------------------------
    // @ Public methods
    // -----------------------------------------------------------------------------------------------------

    forgotPassword(email: string): Observable<any> {
        return this._httpClient.post('api/auth/forgot-password', email);
    }

    resetPassword(password: string): Observable<any> {
        return this._httpClient.post('api/auth/reset-password', password);
    }

    /**
     * Sign in with role-based access
     */
    signIn(credentials: { email: string; password: string }): Observable<any> {
        if (this._authenticated) {
            return throwError(() => new Error('User is already logged in.'));
        }

        return this._httpClient.post(`${environment.apiUrl}/api/user-login`, credentials).pipe(
            switchMap((response: any) => {
                console.log('Login response:', response);
                
                // Store access token
                this.accessToken = response.accessToken;
                
                // Store user role
                if (response.user && response.user.roles) {
                    this.userRole = response.user.roles;
                    console.log('User role set:', response.user.roles);
                }
                
                this._authenticated = true;
                this._userService.user = response.user;
                
                return of(response);
            }),
            catchError((error) => {
                console.error('Login error:', error);
                return throwError(() => error);
            })
        );
    }

    signInUsingToken(): Observable<any> {
        return this._httpClient
            .post(`${environment.apiUrl}/api/verify-token`, {
                token: this.accessToken,
            })
            .pipe(
                catchError((error) => {
                    console.error('Token verification failed:', error);
                    this.accessToken = '';
                    this.clearUserRole();
                    return of(false);
                }),
                switchMap((response: any) => {
                    if (response && response.valid) {
                        this._authenticated = true;
                        this._userService.user = response.user;
                        
                        // Update user role
                        if (response.user && response.user.roles) {
                            this.userRole = response.user.roles;
                        }
                        
                        return of(true);
                    }
                    return of(false);
                })
            );
    }

    signOut(): Observable<any> {
        localStorage.removeItem('accessToken');
        this.clearUserRole();
        this._authenticated = false;
        return of(true);
    }

    signUp(user: {
        name: string;
        email: string;
        password: string;
        company: string;
    }): Observable<any> {
        return this._httpClient.post('api/auth/sign-up', user);
    }

    unlockSession(credentials: {
        email: string;
        password: string;
    }): Observable<any> {
        return this._httpClient.post('api/auth/unlock-session', credentials);
    }

    check(): Observable<boolean> {
        if (this._authenticated) {
            return of(true);
        }

        if (!this.accessToken) {
            return of(false);
        }

        if (AuthUtils.isTokenExpired(this.accessToken)) {
            return of(false);
        }

        return this.signInUsingToken();
    }

    /**
     * Check if user has specific role
     */
    hasRole(role: string): boolean {
        return this.userRole === role;
    }

    /**
     * Check if user has any of the specified roles
     */
    hasAnyRole(roles: string[]): boolean {
        const currentRole = this.userRole;
        return currentRole ? roles.includes(currentRole) : false;
    }

    /**
     * Clear user role from storage
     */
    private clearUserRole(): void {
        localStorage.removeItem('userRole');
        this._currentUserRole.next(null);
    }

    /**
     * Get role-based redirect URL
     */
    getRoleBasedRedirectUrl(): string {
        const role = this.userRole;
        
        switch (role) {
            case 'Management':
                return '/example'; // Dashboard for management
            case 'SuperAdmin':
                return '/example'; // Full admin dashboard
            case 'Admin':
                return '/example'; // Admin dashboard
            case 'Client':
                return '/example'; // Client view - their machines
            case 'Refiller':
                return '/products'; // Refiller view - products
            case 'Servicer':
                return '/machines'; // Servicer view - machines
            default:
                return '/example';
        }
    }
}