import {
  Component,
  OnInit,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  OnDestroy,
} from "@angular/core";
import {
  AbstractControl,
  FormBuilder,
  FormGroup,
  Validators,
} from "@angular/forms";
import {
  MatSnackBarHorizontalPosition,
  MatSnackBarVerticalPosition,
} from "@angular/material/snack-bar";
import { Title } from "@angular/platform-browser";
import { Router } from "@angular/router";
import { NgbModalOptions } from "@ng-bootstrap/ng-bootstrap";
import { Subject, fromEvent, merge } from "rxjs";
import {
  first,
  takeUntil,
  finalize,
  debounceTime,
  distinctUntilChanged,
} from "rxjs/operators";
import { UserService } from "src/app/services/user.service";
import { environment } from "../../../environments/environment";
import { getAllElements } from "src/app/custom/common";
import { AuthenticationService } from 'src/app/core/services/authentication.service';
import { DataService } from 'src/app/core/services/data.service';
import { ConfigurationService } from 'src/app/core/services/configuration.service';
import { LoginOptimizationService } from "src/app/services/login-optimization.service";
import { NavigationService } from "src/app/services/navigation.service";

@Component({
  selector: "app-login",
  templateUrl: "./login.page.html",
  styleUrls: ["./login.page.scss"],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoginPageComponent implements OnInit, OnDestroy {
  public form: FormGroup;
  public forgotPasswordForm: FormGroup;
  public submitted = false;
  public forgotPasswordSubmitted = false;
  public loadingResendCode = false;
  public type: string = "password";
  private destroy$ = new Subject<void>();
  public durationInSeconds = 3;
  public horizontalPosition: MatSnackBarHorizontalPosition = "right";
  public verticalPosition: MatSnackBarVerticalPosition = "bottom";
  public submitted_code: boolean = false;
  public errorLogin = "";
  public hide: boolean = true;

  // Propriétés pour le mot de passe oublié
  public showForgotPassword = false;
  public isForgotPasswordLoading = false;
  public forgotPasswordError = "";
  public forgotPasswordSuccess = "";
  public ngbModalOptions: NgbModalOptions = {
    backdrop: "static",
    keyboard: false,
    centered: true,
  };
  public isLoading = false;
  public loadingProgress = 0;
  public loadingMessage = "";
  public isFormValid = false;
  public connectionAttempts = 0;
  public maxAttempts = 3;
  public isBlocked = false;
  public blockTimeRemaining = 0;
  public selectedElementInfo: any = null; // Informations sur l'élément sélectionné automatiquement
  public previewData: any = null; // Aperçu des données du premier élément
  // Cache pour éviter les appels multiples et optimiser les performances
  private userCache = new Map<string, any>();
  public environment = environment; // Exposer environment pour le template
  constructor(
    private formBuilder: FormBuilder,
    private router: Router,
    public userSerive: UserService,
    private titleService: Title,
    private authService: AuthenticationService,
    private dataService: DataService,
    private configService: ConfigurationService,
    private cdr: ChangeDetectorRef,
    private loginOptimization: LoginOptimizationService,
    private navigationService: NavigationService
  ) {
    this.form = this.formBuilder.group({
      username: ["", [Validators.required]],
      password: ["", [Validators.required]],
    });

    this.forgotPasswordForm = this.formBuilder.group({
      email: ["", [Validators.required, Validators.email]],
    });
  }
  ngOnInit(): void {
    this.titleService.setTitle("Se connecter | ESTAIR-CONNECT ");
    this.setupFormValidation();
    this.setupLoginStateMonitoring();
    this.prefetchInitialData();

    if (environment.production) {
      if (location.protocol === "http:") {
        window.location.href = location.href.replace("http", "https");
      }
    }
  }

  private setupFormValidation(): void {
    // Validation en temps réel pour améliorer l'UX avec debounce
    this.form.valueChanges
      .pipe(takeUntil(this.destroy$), debounceTime(300), distinctUntilChanged())
      .subscribe(() => {
        this.isFormValid = this.form.valid;
        this.checkUserStatus();
        if (this.errorLogin) {
          this.errorLogin = "";
        }
        this.cdr.markForCheck();
      });

    // Validation des champs individuels pour feedback immédiat
    this.form
      .get("username")
      ?.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(500))
      .subscribe(() => this.cdr.markForCheck());

    this.form
      .get("password")
      ?.valueChanges.pipe(takeUntil(this.destroy$), debounceTime(500))
      .subscribe(() => this.cdr.markForCheck());
  }

  private setupLoginStateMonitoring(): void {
    // Surveiller les changements d'état de connexion
    this.loginOptimization.loginStateChanges
      .pipe(takeUntil(this.destroy$))
      .subscribe((state) => {
        this.isBlocked = state.isBlocked;
        this.blockTimeRemaining = state.blockTimeRemaining;
        this.connectionAttempts = this.maxAttempts - state.attemptsRemaining;
        
        // Si le temps de blocage est écoulé, forcer le nettoyage
        if (this.blockTimeRemaining <= 0 && this.isBlocked) {
          this.loginOptimization.forceCleanup();
        }
        
        this.cdr.markForCheck();
      });
  }

  private checkUserStatus(): void {
    const username = this.form.get("username")?.value;
    if (username) {
      this.isBlocked = this.loginOptimization.isUserBlocked(username);
      this.blockTimeRemaining =
        this.loginOptimization.getBlockTimeRemaining(username);
      this.connectionAttempts =
        this.maxAttempts -
        this.loginOptimization.getAttemptsRemaining(username);
    }
  }

  private prefetchInitialData(): void {
    // Utiliser le service d'optimisation pour le préchargement
    this.loginOptimization.prefetchEssentialData(this.userSerive);
  }

  private checkBlockStatus(): void {
    const blockData = localStorage.getItem("loginBlock");
    if (blockData) {
      const parsed = JSON.parse(blockData);
      const now = Date.now();
      if (now < parsed.blockUntil) {
        this.isBlocked = true;
        this.blockTimeRemaining = Math.ceil((parsed.blockUntil - now) / 1000);
        this.startBlockCountdown();
        this.cdr.markForCheck();
      } else {
        localStorage.removeItem("loginBlock");
      }
    }
  }

  private startBlockCountdown(): void {
    const interval = setInterval(() => {
      this.blockTimeRemaining--;
      if (this.blockTimeRemaining <= 0) {
        this.isBlocked = false;
        this.connectionAttempts = 0;
        localStorage.removeItem("loginBlock");
        clearInterval(interval);
      }
      this.cdr.markForCheck();
    }, 1000);
  }

  get f(): { [key: string]: AbstractControl } {
    return this.form.controls;
  }
  public async sumbitLogin() {
    this.submitted = true;
    if (this.form.invalid || this.isLoading || this.isBlocked) {
      return;
    }

    await this.performLogin();
  }

  private async performLogin(): Promise<void> {
    try {
      this.setLoadingState(true, "Connexion en cours...", 10);
      this.errorLogin = "";

      // Étape 1: Authentification avec timeout
      const loginPromise = this.userSerive.login(
        this.form.value.username,
        this.form.value.password
      );

      const loginData = await this.withTimeout(
        loginPromise,
        10000,
        "Délai d'attente dépassé"
      );
      
      if (loginData && !loginData.success) {
        this.handleLoginError(loginData.message);
        this.loginOptimization.recordLoginAttempt(
          this.form.value.username,
          false
        );
        return;
      }

      // Verifier si l'utilisateur doit changer son mot de passe (premiere connexion)
      if (loginData?.data?.must_change_password) {
        const authToken = {
          accessToken: loginData.data.token,
          refreshToken: loginData.data.refresh_token || null,
          expiresAt: Date.now() + (30 * 60 * 1000),
          tokenType: 'Bearer',
        };
        localStorage.setItem("__token", JSON.stringify(authToken));
        this.authService.setToken(authToken);

        // Stocker temporairement en sessionStorage (securite)
        sessionStorage.setItem('__must_change_password', 'true');
        sessionStorage.setItem('__temp_password', this.form.value.password);
        sessionStorage.setItem('__temp_phone', this.form.value.username);

        this.setLoadingState(false);
        this.router.navigate(['/mot-de-passe/premiere-connexion']);
        return;
      }

      this.updateLoadingProgress(30, "Récupération du profil utilisateur...");

      // Étape 2: Récupération des détails utilisateur
      const userDetailPromise = this.userSerive.userdetail(
        loginData.data.token
      );
      const userDetail = await this.withTimeout(
        userDetailPromise,
        8000,
        "Impossible de récupérer le profil"
      );

      if (userDetail && !userDetail.success) {
        this.handleLoginError(userDetail.message);
        return;
      }

      this.updateLoadingProgress(50, "Chargement des menus...");

      // Étape 3: Sauvegarde des données utilisateur
      this.saveUserData(userDetail.data, loginData.data); 
      
      // Étape 4: Chargement parallèle des données initiales (utiliser le cache optimisé)
      await this.loadInitialData();
      await this.waitForUX();

      this.updateLoadingProgress(100, "Redirection...");

      // Succès: enregistrer la tentative réussie et nettoyer
      this.loginOptimization.recordLoginAttempt(this.form.value.username, true);
      this.loginOptimization.resetAttempts(this.form.value.username);
      
      // Redirection dynamique vers le premier élément du menu
      this.redirectToFirstMenuItem();
      this.setLoadingState(false);
    } catch (error) {
      console.error("Erreur lors de la connexion:", error);
      this.handleLoginError(
        error instanceof Error && error.message.includes("Délai")
          ? error.message
          : "Une erreur inattendue s'est produite. Veuillez réessayer."
      );
      this.loginOptimization.recordLoginAttempt(
        this.form.value.username,
        false
      );
    }
  }
  private async navigateAfterLogin(): Promise<void> {
    try {
      console.group("🧭 Navigation après connexion");
      this.updateLoadingProgress(90, "Sauvegarde des données préchargées...");

      // Supprimer le setTimeout qui causait des problèmes
      // setTimeout(() => {
      //   console.log("sleep");
      //   this.router.navigate(["/"]);
      // }, 30000);

      // Vérifier que les données par défaut sont bien configurées
      const domaineDD = localStorage.getItem("__domaineDD");
      console.log("🎯 Données de domaine par défaut:", domaineDD);

      if (!domaineDD) {
        console.warn(
          "⚠️ Aucune donnée de domaine par défaut trouvée - tentative de reconfiguration..."
        );

        // Essayer de reconfigurer avec les menus disponibles
        const menusData = localStorage.getItem("__menus");
        if (menusData) {
          const parsedMenus = JSON.parse(menusData);
          await this.setDefaultElement(parsedMenus);
        }
      }

      // S'assurer que les données préchargées sont bien en cache pour une utilisation immédiate
      if (this.previewData && this.selectedElementInfo) {
        console.log(
          "📋 Informations d'élément sélectionné:",
          this.selectedElementInfo
        );
        console.log("👁️ Données d'aperçu:", this.previewData);

        // Récupérer les vraies données du module qui ont été préchargées
        const moduleDataKey = `__moduleData_${this.selectedElementInfo.moduleName}`;
        const moduleDataString = localStorage.getItem(moduleDataKey);
        let moduleData = null;

        console.log(
          `🔍 Recherche des données du module avec la clé: ${moduleDataKey}`
        );

        if (moduleDataString) {
          try {
            moduleData = JSON.parse(moduleDataString);
            console.log("✅ Données du module récupérées pour la navigation:", {
              module: this.selectedElementInfo.moduleName,
              dataKeys: Object.keys(moduleData || {}),
              itemCount:
                moduleData?.[this.selectedElementInfo.moduleName]?.length || 0,
            });
          } catch (parseError) {
            console.warn(
              "❌ Erreur lors du parsing des données du module:",
              parseError
            );
          }
        } else {
          console.warn(
            `⚠️ Aucune donnée trouvée pour la clé: ${moduleDataKey}`
          );

          // Lister toutes les clés disponibles dans le localStorage pour debug
          const allKeys = Object.keys(localStorage).filter((key) =>
            key.includes("__moduleData")
          );
          console.log("🔍 Clés de données de module disponibles:", allKeys);
        }

        // Également récupérer les données de configuration (liste de vues, CTA, etc.)
        const listViewCacheKey = `listView_${this.selectedElementInfo.moduleName}`;
        const listViewData =
          this.loginOptimization.getCacheData(listViewCacheKey);

        console.log("📋 Données de configuration récupérées:", {
          hasListViewData: !!listViewData,
          cacheKey: listViewCacheKey,
          listViewKeys: listViewData
            ? Object.keys(listViewData.data || {})
            : [],
        });

        const cacheKey = `cache_${this.selectedElementInfo.domainName}_${this.selectedElementInfo.moduleName}`;
        const cacheData = {
          previewData: this.previewData,
          selectedElementInfo: this.selectedElementInfo,
          moduleData: moduleData, // Inclure les vraies données du module
          listViewData: listViewData?.data, // Inclure les configurations de vues
          timestamp: Date.now(),
          autoLoadAfterLogin: true,
        };

        localStorage.setItem(cacheKey, JSON.stringify(cacheData));
        localStorage.setItem("lastCacheKey", cacheKey);
        localStorage.setItem("autoLoadFirstData", "true"); // Flag pour charger automatiquement

        console.log(
          "✅ Données complètes mises en cache pour navigation rapide:",
          {
            cacheKey,
            hasPreviewData: !!cacheData.previewData,
            hasModuleData: !!cacheData.moduleData,
            hasListViewData: !!cacheData.listViewData,
            moduleDataKeys: Object.keys(cacheData.moduleData || {}),
            listViewKeys: Object.keys(cacheData.listViewData || {}),
          }
        );
      } else {
        console.warn(
          "⚠️ Aucune donnée d'aperçu ou d'élément sélectionné disponible"
        );
        console.log("📊 État actuel:", {
          hasPreviewData: !!this.previewData,
          hasSelectedElementInfo: !!this.selectedElementInfo,
          previewData: this.previewData,
          selectedElementInfo: this.selectedElementInfo,
        });
      }

      this.updateLoadingProgress(95, "Préparation de la navigation...");

      // Utiliser le service de navigation sécurisée
      const success = await this.navigationService.navigateAfterLogin();

      if (success) {
        this.setLoadingState(false);
        // Nettoyer l'aperçu après navigation réussie (avec un délai pour permettre l'affichage)
        setTimeout(() => this.cleanupAfterLogin(), 1000);
      } else {
        throw new Error("Navigation échouée");
      }
    } catch (error) {
      console.error("Erreur lors de la navigation post-login:", error);
      this.handleNavigationError();
    }
  }

  private handleNavigationError(): void {
    this.updateLoadingProgress(100, "Finalisation de la connexion...");

    // Essayer une navigation de secours après un délai
    setTimeout(async () => {
      try {
        await this.navigationService.navigateAfterLogin();
        this.setLoadingState(false);
      } catch (secondError) {
        console.error("Seconde tentative de navigation échouée:", secondError);
        // En dernier recours, recharger la page
        window.location.href = "/";
      }
    }, 1500);
  }
  private async loadInitialData(): Promise<void> {
    try {
      console.group("🚀 Chargement des données initiales");
      this.updateLoadingProgress(70, "Chargement des données initiales...");

      // Utiliser le cache optimisé via le service
      let menuData = this.loginOptimization.getCacheData("menus");
      console.log("📋 Données de menu depuis le cache:", menuData);

      if (!menuData) {
        console.log("📡 Chargement des menus depuis l'API...");
        // Utiliser la méthode cachée du service pour de meilleures performances
        menuData = await this.userSerive.getCachedElements("v1/menus", true);
        console.log("📋 Données de menu reçues de l'API:", menuData);

        if (menuData?.data) {
          console.log("💾 Sauvegarde des menus en cache");
          this.loginOptimization.setCacheData("menus", menuData);
        }
      }

      // Sauvegarder les menus
      if (menuData?.data) {
        console.log("💾 Sauvegarde des menus dans localStorage");
        // Extraire le tableau de menus depuis la réponse API
        // L'API retourne {role, menus: [...]} mais le localStorage doit contenir le tableau
        const menusArray = Array.isArray(menuData.data)
          ? menuData.data
          : (menuData.data.menus || []);
        localStorage.setItem("__menus", JSON.stringify(menusArray));
        localStorage.setItem("isFirst", "true");

        // Sélectionner automatiquement le premier élément disponible
        this.updateLoadingProgress(
          75,
          "Configuration de l'élément par défaut..."
        );
        console.log("🎯 Configuration de l'élément par défaut...");
        await this.setDefaultElement(menusArray);
      } else {
        console.warn("⚠️ Aucune donnée de menu disponible");
      }

      // Charger les données additionnelles en parallèle
      const additionalDataPromises: Promise<any>[] = [
        // this.userSerive.getSomeOtherData(),
        // this.userSerive.getPermissions(),
      ];

      if (additionalDataPromises.length > 0) {
        try {
          this.updateLoadingProgress(
            80,
            "Chargement des données complémentaires..."
          );
          console.log("📦 Chargement des données complémentaires...");
          await Promise.all(additionalDataPromises);
        } catch (error) {
          console.warn(
            "Certaines données additionnelles n'ont pas pu être chargées:",
            error
          );
        }
      }

      this.updateLoadingProgress(90, "Finalisation...");
      await this.waitForUX();

      console.log("✅ Chargement des données initiales terminé");
      console.groupEnd();
    } catch (error) {
      console.error(
        "❌ Erreur lors du chargement des données initiales:",
        error
      );
      console.groupEnd();
      // On continue quand même la connexion même si les données secondaires échouent
    }
  }

  /**
   * Configure automatiquement le premier élément disponible pour l'utilisateur
   */
  private async setDefaultElement(menuData: any): Promise<void> {
    try {
      console.group("🎯 Configuration de l'élément par défaut");
      console.log("📋 Données du menu reçues:", menuData);

      // Prendre le premier élément du menu pour déterminer le domaine par défaut
      const firstMenuItem = menuData && Array.isArray(menuData) && menuData.length > 0 ? menuData[0] : null;
      
      let defaultDomainData;
      
      if (firstMenuItem && firstMenuItem.name) {
        // Configuration par défaut selon le nom du premier menu
        const menuName = firstMenuItem.name.toLowerCase();
        
        switch (menuName) {
          case 'vente':
            defaultDomainData = {
              domaine: "vente",
              modulename: "pnr",
              label: "PNR"
            };
            break;
          case 'client':
            defaultDomainData = {
              domaine: "client", 
              modulename: "accounts",
              label: "Comptes"
            };
            break;
          case 'finance':
            defaultDomainData = {
              domaine: "finance",
              modulename: "factures",
              label: "Factures"
            };
            break;
          default:
            defaultDomainData = {
              domaine: menuName,
              modulename: "pnr",
              label: "PNR"
            };
        }
      } else {
        // Configuration par défaut générique
        defaultDomainData = {
          domaine: "vente",
          modulename: "pnr", 
          label: "PNR"
        };
      }
      
      localStorage.setItem("__domaineDD", JSON.stringify(defaultDomainData));
      console.log("✅ Configuration par défaut configurée:", defaultDomainData);

      console.groupEnd();
    } catch (error) {
      console.error(
        "❌ Erreur lors de la configuration de l'élément par défaut:",
        error
      );
      console.groupEnd();
    }
  }
  /**
   * Précharge les données de base pour le module sélectionné
   */
  private async preloadModuleData(domainData: any): Promise<void> {
    try {
      console.group("📦 Préchargement des données du module");
      console.log("🎯 Données du domaine à précharger:", domainData);

      this.updateLoadingProgress(
        85,
        `Préchargement des données ${domainData.modulename}...`
      );

      // Configuration enrichie pour le cache de navigation
      const enrichedCache = {
        selectedElementInfo: {
          title: domainData.modulename,
          domaine: domainData.domaine,
          moduleName: domainData.modulename,
          moduleTitle: domainData.modulename,
          element: domainData,
          timestamp: Date.now(),
        },
        moduleData: {},
        listViewData: null,
        timestamp: Date.now(),
      };

      console.log("🎯 Configuration de base pour le cache:", enrichedCache);

      // Précharger les données du module et les intégrer au cache
      try {
        console.log("📊 Tentative de chargement des données principales...");
        const moduleData = await this.dataService.getAll(
          domainData.domaine,
          domainData.modulename,
          { useCache: true, cacheTtl: 300000 }
        ).toPromise();

        console.log("📊 Données du module reçues:", moduleData);

        if (moduleData && Array.isArray(moduleData) && moduleData.length > 0) {
          console.log("💾 Données du module reçues pour le cache:", {
            count: moduleData.length,
            hasData: moduleData.length > 0,
          });

          // Convertir en format compatible
          const moduleDataFormatted = {
            [domainData.modulename]: moduleData
          };
          enrichedCache.moduleData = moduleDataFormatted;

          // Sauvegarder également en tant que moduleData séparé pour compatibilité
          const moduleDataKey = `__moduleData_${domainData.modulename}`;
          localStorage.setItem(moduleDataKey, JSON.stringify(moduleDataFormatted));
          console.log(
            `✅ Données du module sauvegardées en tant que ${moduleDataKey}`
          );

          // Stocker également dans le service de cache
          this.loginOptimization.setCacheData(
            `moduleData_${domainData.modulename}`,
            { data: moduleDataFormatted }
          );

          const dataCount = moduleData.length;
          console.log(
            `✅ Données du module ${domainData.modulename} préchargées:`,
            dataCount,
            "éléments"
          );

          // Mettre à jour l'aperçu avec le nombre d'éléments réels
          if (this.previewData) {
            this.previewData.dataCount = dataCount;
            this.previewData.hasRealData = true;
            console.log("📊 Aperçu mis à jour:", this.previewData);
            this.cdr.markForCheck();
          }

          console.log("✅ Données du module ajoutées au cache enrichi");
        } else {
          console.warn("⚠️ Aucune donnée module disponible pour le cache");
        }
      } catch (dataError) {
        console.warn(
          `⚠️ Impossible de précharger les données pour ${domainData.modulename}:`,
          dataError
        );
      }

      // Précharger les éléments de vue de liste
      try {
        console.log(
          "📦 Tentative de chargement des éléments de vue de liste..."
        );
        // Migration vers DataService - ListViewElements sera géré différemment
        // Pour l'instant, on simule les données de vue
        const listViewElements = null; // Désactivé temporairement

        console.log("📋 Éléments de vue de liste - fonctionnalité temporairement désactivée");

        // Créer des données de vue par défaut
        const defaultListViewData = {
          [domainData.modulename]: {
            data: {
              ListeView: {
                list: [{ name: 'Liste par défaut' }],
                cta: [{ action: 'Créer', name: 'Nouveau' }],
                badges: []
              }
            }
          }
        };

        enrichedCache.listViewData = defaultListViewData as any;

        // Sauvegarder en cache pour un accès rapide
        this.loginOptimization.setCacheData(
          `listView_${domainData.modulename}`,
          { data: defaultListViewData }
        );

        // Extraire un aperçu des données pour l'affichage
        this.extractPreviewData(defaultListViewData, domainData);

        console.log("✅ Configuration par défaut des vues créée");
      } catch (apiError) {
        console.warn(
          `⚠️ API getListViewElements non disponible pour ${domainData.modulename}:`,
          apiError
        );
      }

      // Sauvegarder le cache enrichi
      const cacheKey = `navigationCache_${Date.now()}`;
      localStorage.setItem(cacheKey, JSON.stringify(enrichedCache));
      localStorage.setItem("lastCacheKey", cacheKey);
      localStorage.setItem("autoLoadFirstData", "true");

      console.log("💾 Cache enrichi sauvegardé:", {
        cacheKey,
        hasModuleData: Object.keys(enrichedCache.moduleData).length > 0,
        hasListViewData: enrichedCache.listViewData !== null,
        totalSize: JSON.stringify(enrichedCache).length,
      });

      console.log(
        `🎯 Préchargement terminé pour le module: ${domainData.modulename}`
      );
      console.groupEnd();
    } catch (error) {
      console.warn(
        `❌ Erreur générale lors du préchargement pour ${domainData.modulename}:`,
        error
      );
      console.groupEnd();
    }
  }

  /**
   * Extrait un aperçu des données pour l'affichage dans la page de login
   */
  private extractPreviewData(listViewData: any, domainData: any): void {
    try {
      // Extraire les informations importantes des données de vue
      const moduleKey = Object.keys(listViewData).find(
        (key) => key.toLowerCase() === domainData.modulename.toLowerCase()
      );

      if (moduleKey && listViewData[moduleKey]?.data?.ListeView) {
        const listeView = listViewData[moduleKey].data.ListeView;

        this.previewData = {
          moduleTitle: domainData.modulename,
          listsCount: listeView.list?.length || 0,
          ctaCount: listeView.cta?.length || 0,
          badgesCount: listeView.badges?.length || 0,
          firstListName: listeView.list?.[0]?.name || "Liste par défaut",
          availableActions:
            listeView.cta
              ?.map((cta: any) => cta.action || cta.name)
              .slice(0, 3) || [],
          hasData: true,
        };

        console.log("Aperçu des données extrait:", this.previewData);
        this.cdr.markForCheck();
      }
    } catch (error) {
      console.warn("Impossible d'extraire l'aperçu des données:", error);
      this.previewData = {
        moduleTitle: domainData.modulename,
        hasData: false,
        error: "Données non disponibles",
      };
      this.cdr.markForCheck();
    }
  }

  private saveUserData(user: any, tokenData: any): void {
    // Utiliser des clés de cache pour éviter les doublons
    const userKey = `user_${user.uuid}`;
    const tokenKey = `token_${tokenData.token}`;

    // Sauvegarder l'utilisateur
    if (!this.userCache.has(userKey)) {
      localStorage.setItem("__user", JSON.stringify(user));
      this.userCache.set(userKey, user);
    }

    // Convertir et sauvegarder le token
    if (!this.userCache.has(tokenKey)) {
      const debugLogs: string[] = [];
      debugLogs.push('🔍 Données du token reçues du backend: ' + JSON.stringify(tokenData));
      console.log('🔍 Données du token reçues du backend:', tokenData);

      // Décoder le JWT pour vérifier l'expiration
      let expiresAt: number;
      try {
        const tokenPayload = JSON.parse(atob(tokenData.token.split('.')[1]));
        debugLogs.push('🔍 Payload du JWT décodé: ' + JSON.stringify(tokenPayload));
        console.log('🔍 Payload du JWT décodé:', tokenPayload);

        // Le JWT contient 'exp' en secondes (timestamp Unix)
        expiresAt = tokenPayload.exp * 1000; // Convertir en millisecondes

        const expirationInfo = {
          expiresAtMs: expiresAt,
          expiresAtDate: new Date(expiresAt).toLocaleString(),
          nowMs: Date.now(),
          nowDate: new Date().toLocaleString(),
          isValid: expiresAt > Date.now(),
          timeRemaining: Math.round((expiresAt - Date.now()) / 1000 / 60) + ' minutes'
        };
        debugLogs.push('🔍 Expiration du token: ' + JSON.stringify(expirationInfo));
        console.log('🔍 Expiration du token:', expirationInfo);
      } catch (error) {
        debugLogs.push('❌ Erreur lors du décodage du JWT: ' + error);
        console.error('❌ Erreur lors du décodage du JWT:', error);
        // Fallback: 24h par défaut
        expiresAt = Date.now() + (24 * 60 * 60 * 1000);
      }

      // Convertir le token au format AuthToken pour AuthenticationService
      const authToken = {
        accessToken: tokenData.token,
        refreshToken: tokenData.refresh_token || null,
        expiresAt: expiresAt,
        tokenType: 'Bearer',
        scope: tokenData.scope || null
      };

      debugLogs.push('💾 Sauvegarde du token au format AuthToken: ' + JSON.stringify(authToken));
      debugLogs.push('💾 Token valide? ' + (expiresAt > Date.now()));
      console.log('💾 Sauvegarde du token au format AuthToken:', authToken);
      console.log('💾 Token valide?', expiresAt > Date.now());

      // Sauvegarder les logs pour debug
      localStorage.setItem('__debug_login_logs', JSON.stringify(debugLogs));
      console.log('📝 Logs sauvegardés dans localStorage - clé: __debug_login_logs');

      localStorage.setItem("__token", JSON.stringify(authToken));
      this.userCache.set(tokenKey, authToken);

      // ✅ IMPORTANT: Notifier l'AuthenticationService du nouveau token
      this.authService.setToken(authToken);
      console.log('✅ Token enregistré dans AuthenticationService');
    }
  }
  private async withTimeout<T>(
    promise: Promise<T>,
    timeoutMs: number,
    errorMessage: string
  ): Promise<T> {
    const timeoutPromise = new Promise<never>((_, reject) => {
      setTimeout(() => reject(new Error(errorMessage)), timeoutMs);
    });

    return Promise.race([promise, timeoutPromise]);
  }
  private setLoadingState(
    loading: boolean,
    message: string = "",
    progress: number = 0
  ): void {
    this.isLoading = loading;
    this.loadingMessage = message;
    this.loadingProgress = progress;

    // Si le chargement se termine, nettoyer les données de prévisualisation après un délai
    if (!loading && (this.selectedElementInfo || this.previewData)) {
      setTimeout(() => {
        this.selectedElementInfo = null;
        this.previewData = null;
        this.cdr.markForCheck();
      }, 2000); // Garder l'aperçu 2 secondes après la fin du chargement
    }

    this.cdr.markForCheck();
  }

  private updateLoadingProgress(progress: number, message: string): void {
    this.loadingProgress = progress;
    this.loadingMessage = message;
    this.cdr.markForCheck();
  }

  private async waitForUX(): Promise<void> {
    // Petit délai pour que l'utilisateur voit la progression
    return new Promise((resolve) => setTimeout(resolve, 200));
  }
  private handleLoginError(message: string): void {
    this.setLoadingState(false);
    this.errorLogin = message;

    // Nettoyer les données de prévisualisation en cas d'erreur
    this.selectedElementInfo = null;
    this.previewData = null;

    this.cdr.markForCheck();
  }
  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
    this.userCache.clear();

    // Nettoyer les données de prévisualisation
    this.selectedElementInfo = null;
    this.previewData = null;
  }

  public showPassword() {
    this.hide = !this.hide;
    this.hide ? (this.type = "password") : (this.type = "text");
  }

  /**
   * Afficher le formulaire de mot de passe oublié
   */
  public showForgotPasswordForm(): void {
    this.showForgotPassword = true;
    this.forgotPasswordError = "";
    this.forgotPasswordSuccess = "";
    this.forgotPasswordSubmitted = false;
    this.forgotPasswordForm.reset();
    this.cdr.markForCheck();
  }

  /**
   * Fermer le formulaire de mot de passe oublié
   */
  public closeForgotPasswordForm(): void {
    this.showForgotPassword = false;
    this.forgotPasswordError = "";
    this.forgotPasswordSuccess = "";
    this.forgotPasswordSubmitted = false;
    this.isForgotPasswordLoading = false;
    this.forgotPasswordForm.reset();
    this.cdr.markForCheck();
  }

  /**
   * Soumettre la demande de réinitialisation du mot de passe
   */
  public async submitForgotPassword(): Promise<void> {
    this.forgotPasswordSubmitted = true;
    this.forgotPasswordError = "";
    this.forgotPasswordSuccess = "";

    if (this.forgotPasswordForm.invalid || this.isForgotPasswordLoading) {
      this.cdr.markForCheck();
      return;
    }

    try {
      this.isForgotPasswordLoading = true;
      this.cdr.markForCheck();

      const email = this.forgotPasswordForm.get('email')?.value;

      console.log('📧 Demande de réinitialisation de mot de passe pour:', email);

      // Simulation d'un appel API - remplacez par votre vraie logique
      await this.sendPasswordResetRequest(email);

      this.forgotPasswordSuccess = `Un lien de réinitialisation a été envoyé à ${email}. Vérifiez vos e-mails.`;

      // Fermer automatiquement après 3 secondes
      setTimeout(() => {
        this.closeForgotPasswordForm();
      }, 3000);

    } catch (error) {
      console.error('❌ Erreur lors de la demande de réinitialisation:', error);

      if (error instanceof Error) {
        this.forgotPasswordError = error.message;
      } else {
        this.forgotPasswordError = "Une erreur est survenue. Veuillez réessayer.";
      }
    } finally {
      this.isForgotPasswordLoading = false;
      this.cdr.markForCheck();
    }
  }

  /**
   * Simuler l'envoi de la demande de réinitialisation (à remplacer par votre vraie API)
   */
  private async sendPasswordResetRequest(email: string): Promise<void> {
    // Simulation d'un délai réseau
    await new Promise(resolve => setTimeout(resolve, 2000));

    // Simuler une validation d'email
    if (!email.includes('@')) {
      throw new Error('Adresse e-mail invalide');
    }

    // Ici vous intégreriez votre vraie API
    // Exemple :
    // return this.authService.resetPassword(email).toPromise();

    // Pour la démo, on simule une réussite
    console.log(`✅ E-mail de réinitialisation envoyé à ${email}`);
  }

  /**
   * Nettoie les données d'aperçu après une navigation réussie
   */
  private cleanupAfterLogin(): void {
    this.selectedElementInfo = null;
    this.previewData = null;
    console.log("🧹 Nettoyage des données d'aperçu après connexion réussie");
    this.cdr.markForCheck();
  }

  public clearLoginBlocking(): void {
    // Nettoyer toutes les données de blocage
    this.loginOptimization.clearAllData();
    localStorage.removeItem('loginBlock');
    
    // Réinitialiser l'état
    this.isBlocked = false;
    this.blockTimeRemaining = 0;
    this.connectionAttempts = 0;
    this.errorLogin = '';
    
    this.cdr.markForCheck();
  }

  /**
   * Redirection vers le premier élément du menu
   */
  private redirectToFirstMenuItem(): void {
    console.log('🎯 Redirection vers le dashboard après login...');

    // Toujours rediriger vers le dashboard après login
    this.router.navigate(['/admin/dashboard/reporting']);

    /* Ancien code de redirection vers le premier menu (désactivé)
    try {
      // Récupérer les données de menu depuis localStorage
      const menusData = localStorage.getItem('__menus');
      
      if (!menusData) {
        console.warn('⚠️ Aucune donnée de menu trouvée, redirection vers dashboard par défaut');
        this.router.navigate(['/admin/dashboard/reporting']);
        return;
      }

      const menus = JSON.parse(menusData);
      console.log('📋 Données de menu disponibles:', menus);

      if (!Array.isArray(menus) || menus.length === 0) {
        console.warn('⚠️ Menu vide, redirection vers dashboard par défaut');
        this.router.navigate(['/admin/dashboard/reporting']);
        return;
      }

      // Prendre le premier élément du menu
      const firstMenuItem = menus[0];
      console.log('🎯 Premier élément de menu:', firstMenuItem);

      // Construire la route basée sur la structure du premier élément
      let route = '/admin';
      
      if (firstMenuItem.name) {
        route += `/${firstMenuItem.name}`;
        
        // Définir des modules préférés selon le nom du menu
        const preferredModulesByMenuName: { [key: string]: string[] } = {
          'Vente': ['pnr', 'billets', 'clients'],
          'Client': ['accounts', 'clients', 'factures'],
          'Administration': ['users', 'config', 'settings'],
          'Finance': ['factures', 'commissions', 'payments']
        };
        
        // Choisir un module préféré selon le nom du menu
        const menuSpecificModules = preferredModulesByMenuName[firstMenuItem.name];
        let selectedModule = 'pnr'; // Module par défaut
        
        if (menuSpecificModules && menuSpecificModules.length > 0) {
          selectedModule = menuSpecificModules[0]; // Prendre le premier module préféré
          console.log('🎯 Module sélectionné selon le nom du menu:', selectedModule);
        } else {
          // Utiliser une liste de modules génériques préférés
          const generalPreferredModules = ['pnr', 'accounts', 'clients', 'billets', 'factures'];
          selectedModule = generalPreferredModules[0];
          console.log('🎯 Module par défaut sélectionné:', selectedModule);
        }
        
        // Si l'élément a une propriété modules, utiliser la logique existante
        if (firstMenuItem.modules && Array.isArray(firstMenuItem.modules) && firstMenuItem.modules.length > 0) {
          console.log('🎯 Modules disponibles dans le menu:', firstMenuItem.modules);
          
          // Chercher si un de nos modules préférés est disponible
          const availablePreferred = (menuSpecificModules || ['pnr']).find(mod => 
            firstMenuItem.modules.includes(mod)
          );
          
          if (availablePreferred) {
            selectedModule = availablePreferred;
            console.log('✅ Module préféré trouvé dans les modules du menu:', selectedModule);
          } else if (firstMenuItem.modules.length > 0) {
            // Si aucun module préféré, éviter "test" si possible
            const nonTestModules = firstMenuItem.modules.filter((m: any) => m !== 'test');
            selectedModule = nonTestModules.length > 0 ? nonTestModules[0] : firstMenuItem.modules[0];
            console.log('🔄 Module sélectionné depuis la liste disponible:', selectedModule);
          }
        }
        
        route += `/${selectedModule}`;
        // route += '/list'; // Ajouter /list par défaut pour accéder à la vue liste
        
        console.log('🎯 Module final sélectionné:', selectedModule);
      }

      console.log('🎯 Route construite:', route);
      console.log('🎯 Redirection vers:', route);
      
      this.router.navigate([route]);

    } catch (error) {
      console.error('❌ Erreur lors de la construction de la route de menu:', error);
      console.log('🎯 Redirection de secours vers dashboard');
      this.router.navigate(['/admin/dashboard/reporting']);
    }
    */
  }
}