import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
import { User } from "src/app/models/user";
import { StorageService } from 'src/app/core/services/storage.service';
import { ProjectsStore } from "src/app/stores/projects.store";
import { UserStore } from "src/app/stores/user.store";
import { environment } from "../../environments/environment";

@Injectable({
  providedIn: "root",
})
export class UserService {
  // Cache pour les réponses API
  private apiCache = new Map<string, { data: any; timestamp: number }>();
  private readonly CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
  private cacheCleanupInterval: any;

  constructor(
    private http: HttpClient,
    private router: Router,
    public storage: StorageService,
    public userStore: UserStore,
    public projectStore: ProjectsStore
  ) {
    // Démarrer le nettoyage automatique du cache
    this.startCacheCleanup();
  }

  private startCacheCleanup(): void {
    // Nettoyer le cache toutes les 2 minutes
    this.cacheCleanupInterval = setInterval(() => {
      this.cleanExpiredCache();
    }, 2 * 60 * 1000);
  }

  public ngOnDestroy(): void {
    if (this.cacheCleanupInterval) {
      clearInterval(this.cacheCleanupInterval);
    }
  }
  public setUserLoggedIn() {}

  public getUserLoggedIn() {}

  // ========== Méthodes API optimisées ==========
  public getAllElements(url: string): Promise<any> {
    const headers = this.createApiHeaders(environment.X_APY_KEY);
    return this.http
      .get<any>(`${environment.API_URL}${url}`, { headers })
      .toPromise();
  }

  public getAllElementsWithAuth(url: string): Promise<any> {
    const headers = this.createAuthHeaders();
    return this.http
      .get<any>(`${environment.API_URL}${url}`, { headers })
      .toPromise();
  }

  public getCachedElements(url: string, useAuth = false): Promise<any> {
    // Vérifier le cache d'abord
    const cacheKey = `${url}_${useAuth}`;
    const cached = this.apiCache.get(cacheKey);

    if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {
      return Promise.resolve(cached.data);
    }

    // Si pas en cache, faire l'appel API
    const apiCall = useAuth
      ? this.getAllElementsWithAuth(url)
      : this.getAllElements(url);

    return apiCall
      .then((data) => {
        if (data && data.success) {
          this.apiCache.set(cacheKey, {
            data,
            timestamp: Date.now(),
          });
        }
        return data;
      })
      .catch((error) => {
        console.error(`Erreur lors de la récupération de ${url}:`, error);
        throw error;
      });
  }
  public login(identifier: string, password: string): Promise<any> {
    const headers = this.createApiHeaders(environment.AUTH_APY_KEY);
    const options = { headers };
    return this.http
      .post<any>(
        `${environment.AUTH_URL}login`,
        {
          phone: identifier,
          password: password,
        },
        options
      )
      .toPromise()
      .catch((error) => {
        console.error("Erreur lors de la connexion:", error);
        throw error;
      });
  }

  public userdetail(token: string): Promise<any> {
    const headers = this.createAuthHeaders(token);
    const options = { headers };
    return this.http
      .get<any>(`${environment.AUTH_URL}user`, options)
      .toPromise()
      .catch((error) => {
        console.error(
          "Erreur lors de la récupération des détails utilisateur:",
          error
        );
        throw error;
      });
  }
  public logOut(sessionId: String) {
    // this.userStore.setUser({});
    // this.projectStore.resetStoreProject();
    this.storage.clear();
    //return true;
    return this.http
      .post<any>(`${environment.API_URL}v1/logout`, {
        sessionId: sessionId,
        setup: `${environment.SETUP}`,
      })
      .pipe(
        map((user) => {
          this.userStore.setUser({});
          this.projectStore.resetStoreProject();
          this.storage.clear();

          return user;
        })
      );
  }
  public setSessionExpired() {
    // Nettoyer le cache avant de vider la session
    this.clearCache();

    this.userStore.setUser({});
    this.projectStore.resetStoreProject();
    this.projectStore.setCurrentTab({});
    this.projectStore.setDomaineDrivenAndModulename({});
    this.storage.removeItem("znak");
    this.storage.clear();
    this.router.navigateByUrl("/login");
  }

  // ========== Méthodes de gestion du cache ==========
  public clearCache(): void {
    this.apiCache.clear();
  }

  public clearCacheByKey(key: string): void {
    // Supprimer toutes les entrées de cache qui contiennent la clé
    for (const cacheKey of this.apiCache.keys()) {
      if (cacheKey.includes(key)) {
        this.apiCache.delete(cacheKey);
      }
    }
  }

  private cleanExpiredCache(): void {
    const now = Date.now();
    for (const [key, entry] of this.apiCache.entries()) {
      if (now - entry.timestamp > this.CACHE_DURATION) {
        this.apiCache.delete(key);
      }
    }
  }

  // ========== Méthodes utilitaires privées ==========
  private createApiHeaders(
    apiKey: string = environment.X_APY_KEY
  ): HttpHeaders {
    return new HttpHeaders({
      "X-API-KEY": apiKey,
    });
  }

  private createAuthHeaders(token?: string): HttpHeaders {
    const tokenData = this.storage.getItem("__token");
    const storedToken = token || (tokenData ? JSON.parse(tokenData)?.token : null);
    return new HttpHeaders({
      "Content-Type": "application/json",
      Authorization: `Bearer ${storedToken}`,
      "X-API-KEY": environment.AUTH_APY_KEY,
    });
  }
}
