import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; // Aggiungi HttpParams
import { BehaviorSubject, Observable, tap } from 'rxjs';
import { Router } from '@angular/router';

// Interfaccia per i dati utente (dal payload del token o dalla risposta /api/me)
export interface User {
  id: number;
  name: string;
  email: string;
  role: 'admin' | 'operator';
  structure_id?: number | null;
}

// Interfaccia per la risposta del login
interface LoginResponse {
  message: string;
  access_token: string;
  token_type: string;
  expires_in: number;
  user: User;
}

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private apiUrl = 'http://localhost:8000/api'; // URL base API
  private tokenKey = 'nursery_auth_token'; // Chiave per localStorage
  private userKey = 'nursery_auth_user';   // Chiave per localStorage

  // BehaviorSubject per tenere traccia dello stato di autenticazione
  // Inizializza leggendo da localStorage per persistere lo stato tra refresh
  private isAuthenticatedSubject = new BehaviorSubject<boolean>(this.hasToken());
  isAuthenticated$ = this.isAuthenticatedSubject.asObservable();

  // BehaviorSubject per i dati dell'utente loggato
  private currentUserSubject = new BehaviorSubject<User | null>(this.getUserFromStorage());
  currentUser$ = this.currentUserSubject.asObservable();

  constructor(private http: HttpClient, private router: Router) { }

  // Metodo per effettuare il login
  login(credentials: { email: string, password: string }): Observable<LoginResponse> {
     // Usiamo x-www-form-urlencoded perché ha funzionato con curl
     const body = new HttpParams({ fromObject: credentials });
     const httpOptions = {
        headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' })
     };

    return this.http.post<LoginResponse>(`${this.apiUrl}/login`, body.toString(), httpOptions).pipe(
      tap(response => {
        // Salva token e utente dopo login successo
        this.saveAuthData(response.access_token, response.user);
        this.isAuthenticatedSubject.next(true); // Aggiorna stato autenticazione
        this.currentUserSubject.next(response.user); // Aggiorna utente corrente
      })
    );
  }

  // Metodo per effettuare il logout
  logout(): void {
    this.removeAuthData(); // Rimuovi token e utente
    this.isAuthenticatedSubject.next(false); // Aggiorna stato
    this.currentUserSubject.next(null); // Aggiorna utente
    this.router.navigate(['/login']); // Reindirizza al login
  }

  // Salva token e dati utente in localStorage
  private saveAuthData(token: string, user: User): void {
    localStorage.setItem(this.tokenKey, token);
    localStorage.setItem(this.userKey, JSON.stringify(user));
  }

  // Rimuove token e dati utente da localStorage
  private removeAuthData(): void {
    localStorage.removeItem(this.tokenKey);
    localStorage.removeItem(this.userKey);
  }

  // Recupera il token da localStorage
  getToken(): string | null {
    return localStorage.getItem(this.tokenKey);
  }

  // Verifica se un token è presente
  private hasToken(): boolean {
    return !!this.getToken();
  }

  // Recupera i dati utente da localStorage
  private getUserFromStorage(): User | null {
    const userString = localStorage.getItem(this.userKey);
    return userString ? JSON.parse(userString) : null;
  }

   // Metodo per ottenere i dati dell'utente corrente (utile per i componenti)
   getCurrentUser(): User | null {
       return this.currentUserSubject.value;
   }

   // Metodo per verificare se l'utente ha un certo ruolo
   hasRole(role: 'admin' | 'operator'): boolean {
       const user = this.getCurrentUser();
       return !!user && user.role === role;
   }

   // TODO: Implementare refresh token se necessario
   // TODO: Implementare chiamata a /api/me per verificare validità token all'avvio app?
}
