import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { BehaviorSubject } from "rxjs";
import { map, tap } from "rxjs/operators";
import { EventService } from 'src/app/core/services/event.service';
import { HttpClientService } from 'src/app/core/services/http-client.service';
import { DataService } from 'src/app/core/services/data.service';
import { AuthenticationService } from 'src/app/core/services/authentication.service';
import { ToastService } from "src/app/services/toast.service";

import { DocumentStore } from "src/app/stores/documents.store";

import { ProjectsStore } from "src/app/stores/projects.store";

import { UserStore } from "src/app/stores/user.store";
import { environment } from "../../environments/environment";
import { StorageService } from "src/app/core/services/storage.service";

@Injectable({
  providedIn: "root",
})
export class ProjectService {
  public current_id!: string;
  public editData$: BehaviorSubject<string> = new BehaviorSubject<any>("");

  constructor(
    private http: HttpClient,
    public projectStore: ProjectsStore,

    public storage: StorageService,
    public userStore: UserStore,

    private httpClientService: HttpClientService,
    private dataService: DataService,
    private authService: AuthenticationService,
    private simulations: EventService,

    private router: Router,

    private documentStore: DocumentStore,

    private toast: ToastService
  ) {
    this.userStore
      .select("user")
      .pipe(
        tap((res: any) => {
          if (res.accessKey) this.current_id = res.userInfo.userId;
        })
      )
      .subscribe();
  }

  async addObject(data: any, elementType: any): Promise<any> {
    return this.httpClientService.post<any>(
      elementType,
      {
        element: data,
        setup: environment.SETUP,
      },
      { domain: 'data' }
    ).toPromise();
  }

  // recursive function
  public removeEmpty(obj: any): any {
    return Object.entries(obj)
      .filter(([_, v]) => v !== "")
      .reduce(
        (acc, [k, v]) => ({
          ...acc,
          [k]: v === Object(v) ? this.removeEmpty(v) : v,
        }),
        {}
      );
  }
  public massEdit(data: any, ids: [], modulename: String) {
    let new_object = this.removeEmpty(data);
    return this.httpClientService.put<any>(
      `admin/${modulename}`,
      {
        data: data,
        ids: ids,
      },
      { domain: 'data' }
    ).pipe(
      map((projects) => {
        if (projects.success) {
          let new_data = ids.map((res: any) => {
            return { ...new_object, projetsid: res };
          });

          this.projectStore.editMass(new_data);
        }
        return projects;
      })
    );
  }

  public massExecute(payload: any, modulename: string) {
    return this.httpClientService.post<any>(
      `admin/${modulename}/spc/execute`,
      payload,
      { domain: 'data' }
    ).pipe(
      map((response) => {
        if (response.success) {
          console.log(
            `Execution en masse reussie pour le module ${modulename}`
          );
        } else {
          console.log(
            `Echec de l'execution en masse pour le module ${modulename}`
          );
        }

        // Utiliser le nouveau systeme de cache pour invalider
        this.httpClientService.invalidateCache(new RegExp(`.*${modulename}.*`));

        return response;
      })
    );
  }

  /**
   * Execute une operation SPC (Amadeus Selling Platform Connect)
   */
  public executeSpcOperation(spcPayload: any, modulename: string) {
    return this.httpClientService.post<any>(
      `admin/${modulename}/spc/execute`,
      spcPayload,
      { domain: 'data' }
    ).pipe(
      map((response) => {
        if (response.success) {
          console.log(
            `Operation SPC ${spcPayload.operation_type} executee avec succes pour ${modulename}`
          );
        } else {
          console.log(
            `Echec de l'operation SPC ${spcPayload.operation_type} pour ${modulename}`
          );
        }

        // Invalider le cache pour le module concerne
        this.httpClientService.invalidateCache(new RegExp(`.*${modulename}.*`));

        return response;
      })
    );
  }

  /**
   * Vide le cache des donnees pour forcer le rafraichissement
   */
  private clearModuleDataCache(modulename: string): void {
    try {
      // Vider les donnees du module specifique dans le localStorage
      const existingData = localStorage.getItem("__datas");
      if (existingData) {
        const parsedData = JSON.parse(existingData);
        if (parsedData[modulename]) {
          delete parsedData[modulename];
          localStorage.setItem("__datas", JSON.stringify(parsedData));
          console.log(`Cache vide pour le module: ${modulename}`);
        }
      }

      // Forcer les indicateurs de rechargement
      localStorage.setItem("__initMetadatas", "true");
      localStorage.setItem("__initDatas", "true");
      localStorage.setItem("isFirst", "true");

      console.log("Indicateurs de rafraichissement configures");
    } catch (error) {
      console.error("Erreur lors du vidage du cache:", error);
    }
  }
  public removeProject(data: [], modulename: string) {
    return this.dataService.deleteMultiple('data', modulename, data)
      .pipe(
        map((projects) => {
          return projects;
        })
      );
  }

  public getByModule(modulename: string, keyword: string) {
    return this.dataService.search('data', modulename, keyword)
      .pipe(
        map((resultAutocompletion: any) => {
          return Array.isArray(resultAutocompletion)
            ? this.formaAutoCompletionProject(resultAutocompletion)
            : [];
        })
      );
  }

  public formaAutoCompletionProject(data: any) {
    let response = data.map((res: any) => {
      return { id: res.id, name: res.value };
    });

    return response ? response : [];
  }
}
