import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { LoginRequest, RegisterRequest, RegisterResponse, LoginResponse, CurrentUser } from '../models/auth.models';

@Injectable({ providedIn: 'root' })
export class AuthService {
  private readonly apiBase = environment.apiBaseUrl;
  private readonly accountServiceUrl = environment.accountServiceUrl;
  private readonly http = inject(HttpClient);

  private currentUserSubject = new BehaviorSubject<CurrentUser | null>(null);
  public currentUser$ = this.currentUserSubject.asObservable();

  constructor() {
    this.loadCurrentUser();
  }

  login(username: string, password: string): Observable<LoginResponse> {
    return this.http
      .post<LoginResponse>(`${this.accountServiceUrl}/api/account/login`, {
        username,
        password
      })
      .pipe(
        tap((response) => {
          localStorage.setItem('token', response.accessToken); //GRRRRRRRRRR
          localStorage.setItem('refreshToken', response.refreshToken);
          localStorage.setItem('username', username);
          this.getCurrentUser().subscribe();
        })
      );
  }

  register(username: string, password: string, email?: string): Observable<RegisterResponse> {
    return this.http
      .post<RegisterResponse>(`${this.accountServiceUrl}/api/account`, {
        username,
        password,
        email
      })
      .pipe(
        switchMap((response) =>
          this.login(username, password).pipe(map(() => response))
        )
      );
  }

  getCurrentUser(): Observable<CurrentUser> {
    return this.http.get<CurrentUser>(`${this.accountServiceUrl}/api/account/me`).pipe(
      tap((user) => {
        localStorage.setItem('username', user.username);
        localStorage.setItem('userId', user.id);
        this.currentUserSubject.next(user);
      })
    );
  }

  logout(): void {
    localStorage.removeItem('token');
    localStorage.removeItem('refreshToken');
    localStorage.removeItem('username');
    localStorage.removeItem('userId');
    this.currentUserSubject.next(null);
  }

  isLoggedIn(): boolean {
    return !!localStorage.getItem('token');
  }

  private loadCurrentUser(): void {
    const token = localStorage.getItem('token');
    const username = localStorage.getItem('username');
    const userId = localStorage.getItem('userId');
    if (token && username && userId) {
      // Try to verify token is still valid by fetching current user
      this.getCurrentUser().subscribe({
        error: () => {
          // Token is invalid, clear it
          this.logout();
        }
      });
    }
  }
}
