import { Component, inject, OnInit, Input, Output, EventEmitter, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgIcon } from '@ng-icons/core';
import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
import { Subject, takeUntil } from 'rxjs';

import { 
  User,
  UpdateUserDto,
  UserRole,
  UserType,
  UserUtils
} from '@core/models/dcb-bo-hub-user.model';

import { HubUsersService } from '../hub-users.service';
import { RoleManagementService } from '@core/services/hub-users-roles-management.service';
import { AuthService } from '@core/services/auth.service';

@Component({
  selector: 'app-hub-user-profile',
  standalone: true,
  imports: [CommonModule, FormsModule, NgIcon, NgbAlertModule],
  templateUrl: './hub-users-profile.html',
  styles: [`
    .avatar-lg {
      width: 80px;
      height: 80px;
    }
    .fs-24 {
      font-size: 24px;
    }
  `]
})
export class HubUserProfile implements OnInit, OnDestroy {
  private hubUsersService = inject(HubUsersService);
  private roleService = inject(RoleManagementService);
  private authService = inject(AuthService);
  private cdRef = inject(ChangeDetectorRef);
  private destroy$ = new Subject<void>();

  readonly UserRole = UserRole;
  readonly UserType = UserType;
  readonly UserUtils = UserUtils;

  @Input() userId!: string;
  @Output() back = new EventEmitter<void>();
  @Output() resetPasswordRequested = new EventEmitter<string>();

  user: User | null = null;
  loading = false;
  saving = false;
  error = '';
  success = '';

  // Gestion des permissions
  currentUserRole: UserRole | null = null;
  
  // Édition
  isEditing = false;
  editedUser: UpdateUserDto = {};
  
  // Gestion des rôles
  availableRoles: { value: UserRole; label: string; description: string }[] = [];
  updatingRole = false;

  // Getters pour la logique conditionnelle
  get isHubUser(): boolean {
    return UserUtils.isHubUser(this.user!);
  }

  userHasRole(user: User, role: UserRole): boolean {
    return UserUtils.hasRole(user, role);
  }

  ngOnInit() {
    if (this.userId) {
      this.loadCurrentUserPermissions();
      this.loadAvailableRoles();
      this.loadUserProfile();
    }
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  /**
   * Charge les permissions de l'utilisateur courant
   */
  private loadCurrentUserPermissions(): void {
    this.authService.getUserProfile()
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (profile) => {
          this.currentUserRole = this.authService.getCurrentUserRole();
          this.cdRef.detectChanges();
        },
        error: (error) => {
          console.error('Error loading user permissions:', error);
        }
      });
  }

  /**
   * Charge les rôles disponibles pour les utilisateurs Hub
   */
  private loadAvailableRoles(): void {
    this.hubUsersService.getAvailableHubRoles()
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (response) => {
          this.availableRoles = response.roles.map(role => ({
            value: role.value,
            label: role.label,
            description: role.description
          }));
          this.cdRef.detectChanges();
        },
        error: (error) => {
          console.error('Error loading available roles:', error);
          // Fallback pour les rôles Hub
          this.availableRoles = [
            { value: UserRole.DCB_ADMIN, label: 'DCB Admin', description: 'Administrateur système' },
            { value: UserRole.DCB_SUPPORT, label: 'DCB Support', description: 'Support technique' },
            { value: UserRole.DCB_PARTNER, label: 'DCB Partner', description: 'Partenaire commercial' }
          ];
          this.cdRef.detectChanges();
        }
      });
  }

  loadUserProfile() {
    this.loading = true;
    this.error = '';

    this.hubUsersService.getHubUserById(this.userId)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (user) => {
          this.user = user;
          this.loading = false;
          this.cdRef.detectChanges(); 
        },
        error: (error) => {
          this.error = 'Erreur lors du chargement du profil utilisateur Hub';
          this.loading = false;
          this.cdRef.detectChanges(); 
          console.error('Error loading hub user profile:', error);
        }
      });
  }

  startEditing() {
    if (!this.canEditUser()) {
      this.error = 'Vous n\'avez pas la permission de modifier cet utilisateur';
      return;
    }

    this.isEditing = true;
    this.editedUser = {
      firstName: this.user?.firstName,
      lastName: this.user?.lastName,
      email: this.user?.email,
      enabled: this.user?.enabled
    };
    this.cdRef.detectChanges(); 
  }

  cancelEditing() {
    this.isEditing = false;
    this.editedUser = {};
    this.error = '';
    this.success = '';
    this.cdRef.detectChanges(); 
  }

  saveProfile() {
    if (!this.user || !this.canEditUser()) return;

    this.saving = true;
    this.error = '';
    this.success = '';

    this.hubUsersService.updateHubUser(this.user.id, this.editedUser)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (updatedUser) => {
          this.user = updatedUser;
          this.isEditing = false;
          this.saving = false;
          this.success = 'Profil mis à jour avec succès';
          this.editedUser = {};
          this.cdRef.detectChanges(); 
        },
        error: (error) => {
          this.error = this.getErrorMessage(error);
          this.saving = false;
          this.cdRef.detectChanges(); 
          console.error('Error updating hub user:', error);
        }
      });
  }

  updateUserRole(newRole: UserRole) {
    if (!this.user || !this.canManageRoles()) {
      this.error = 'Vous n\'avez pas la permission de modifier les rôles';
      return;
    }

    if (newRole === this.currentUserRole) {
      this.error = 'L\'utilisateur a déjà ce rôle comme rôle principal';
      return;
    }

    // Vérifier que l'utilisateur peut attribuer ce rôle
    if (!this.roleService.canAssignRole(this.currentUserRole, newRole)) {
      this.error = 'Vous n\'avez pas la permission d\'attribuer ce rôle';
      return;
    }

    // Vérifier que le rôle est valide pour les utilisateurs Hub
    if (!this.isValidHubRole(newRole)) {
      this.error = 'Rôle invalide pour un utilisateur Hub';
      return;
    }

    this.updatingRole = true;
    this.error = '';
    this.success = '';

    this.hubUsersService.updateHubUserRole(this.user.id, newRole)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (updatedUser) => {
          this.user = updatedUser;
          this.updatingRole = false;
          this.success = 'Rôle mis à jour avec succès';
          this.cdRef.detectChanges(); 
        },
        error: (error) => {
          this.updatingRole = false;
          this.error = this.getErrorMessage(error);
          this.cdRef.detectChanges(); 
        }
      });
  }

  // Gestion du statut
  enableUser() {
    if (!this.user || !this.canEnableDisableUser()) return;

    this.hubUsersService.enableHubUser(this.user.id)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (updatedUser) => {
          this.user = updatedUser;
          this.success = 'Utilisateur Hub activé avec succès';
          this.cdRef.detectChanges();
        },
        error: (error) => {
          this.error = this.getErrorMessage(error);
          this.cdRef.detectChanges();
        }
      });
  }

  disableUser() {
    if (!this.user || !this.canEnableDisableUser()) {
      this.error = 'Vous n\'avez pas la permission de désactiver cet utilisateur';
      return;
    }

    this.error = '';
    this.success = '';

    this.hubUsersService.disableHubUser(this.user.id)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (updatedUser) => {
          this.user = updatedUser;
          this.success = 'Utilisateur Hub désactivé avec succès';
          this.cdRef.detectChanges(); 
        },
        error: (error) => {
          this.error = this.getErrorMessage(error);
          this.cdRef.detectChanges(); 
          console.error('Error disabling hub user:', error);
        }
      });
  }

  // Réinitialisation du mot de passe
  resetPassword() {
    if (this.user && this.canResetPassword()) {
      this.resetPasswordRequested.emit(this.user.id);
    }
  }

  // ==================== VÉRIFICATIONS DE PERMISSIONS ====================

  /**
   * Vérifie si l'utilisateur peut éditer cet utilisateur
   */
  canEditUser(): boolean {
    // Toujours permettre d'éditer son propre profil
    if (this.isCurrentUserProfile()) {
      return true;
    }

    // Pour les utilisateurs Hub, utiliser les permissions du service de rôle
    return this.roleService.canEditUsers(this.currentUserRole);
  }

  /**
   * Vérifie si l'utilisateur peut gérer les rôles
   */
  canManageRoles(): boolean {
    // Pour les Hub, utiliser les permissions du service de rôle
    return this.roleService.canManageRoles(this.currentUserRole);
  }

  /**
   * Vérifie si l'utilisateur peut activer/désactiver cet utilisateur
   */
  canEnableDisableUser(): boolean {
    // Empêcher la désactivation de soi-même
    if (this.isCurrentUserProfile()) {
      return false;
    }

    // Pour les Hub, utiliser les permissions du service de rôle
    return this.roleService.canEditUsers(this.currentUserRole);
  }

  /**
   * Vérifie si l'utilisateur peut réinitialiser le mot de passe
   */
  canResetPassword(): boolean {
    // Les utilisateurs peuvent réinitialiser leur propre mot de passe
    if (this.isCurrentUserProfile()) {
      return true;
    }
    
    // Pour les Hub, utiliser les permissions générales
    return this.roleService.canEditUsers(this.currentUserRole);
  }

  /**
   * Vérifie si l'utilisateur peut supprimer cet utilisateur
   */
  canDeleteUser(): boolean {
    // Empêcher la suppression de soi-même
    if (this.isCurrentUserProfile()) {
      return false;
    }
    
    // Pour les Hub, utiliser les permissions du service de rôle
    return this.roleService.canDeleteUsers(this.currentUserRole);
  }

  // ==================== UTILITAIRES D'AFFICHAGE ====================

  getStatusBadgeClass(): string {
    if (!this.user) return 'badge bg-secondary';
    if (!this.user.enabled) return 'badge bg-danger';
    if (!this.user.emailVerified) return 'badge bg-warning';
    return 'badge bg-success';
  }

  getStatusText(): string {
    if (!this.user) return 'Inconnu';
    if (!this.user.enabled) return 'Désactivé';
    if (!this.user.emailVerified) return 'Email non vérifié';
    return 'Actif';
  }

  formatTimestamp(timestamp: number): string {
    if (!timestamp) return 'Non disponible';
    return new Date(timestamp).toLocaleDateString('fr-FR', {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    });
  }

  getUserInitials(): string {
    if (!this.user) return 'U';
    return (this.user.firstName?.charAt(0) || '') + (this.user.lastName?.charAt(0) || '') || 'U';
  }

  getUserDisplayName(): string {
    if (!this.user) return 'Utilisateur Hub';
    if (this.user.firstName && this.user.lastName) {
      return `${this.user.firstName} ${this.user.lastName}`;
    }
    return this.user.username;
  }

  getRoleBadgeClass(role: string | UserRole): string {
    return this.roleService.getRoleBadgeClass(role);
  }

  getRoleLabel(role: string | UserRole): string {
    return this.roleService.getRoleLabel(role);
  }

  getRoleIcon(role: string | UserRole): string {
    return this.roleService.getRoleIcon(role);
  }

  getRoleDescription(role: string | UserRole): string {
    const roleInfo = this.availableRoles.find(r => r.value === role);
    return roleInfo?.description || 'Description non disponible';
  }

  // Obtenir le rôle (peut être string ou UserRole)
  getUserRole(): string | UserRole | undefined {
    return this.user?.role;
  }

  // Pour le template, retourner un tableau pour la boucle
  getUserRoles(): (string | UserRole)[] {
    const role = this.user?.role;
    if (!role) return [];
    return Array.isArray(role) ? role : [role];
  }

  // Afficher le rôle
  getUserRoleDisplay(): string {
    if (!this.user) return 'Aucun rôle';
    return this.getRoleLabel(this.user.role);
  }

  // ==================== GESTION DES ERREURS ====================

  private getErrorMessage(error: any): string {
    if (error.error?.message) {
      return error.error.message;
    }
    if (error.status === 400) {
      return 'Données invalides. Vérifiez les informations saisies.';
    }
    if (error.status === 403) {
      return 'Vous n\'avez pas les permissions pour effectuer cette action.';
    }
    if (error.status === 404) {
      return 'Utilisateur non trouvé.';
    }
    if (error.status === 409) {
      return 'Conflit de données. Cet utilisateur existe peut-être déjà.';
    }
    return 'Erreur lors de l\'opération. Veuillez réessayer.';
  }

  // ==================== MÉTHODES DE NAVIGATION ====================

  goBack() {
    this.back.emit();
  }

  // ==================== MÉTHODES DE VALIDATION ====================

  isFormValid(): boolean {
    if (!this.editedUser.firstName?.trim() || !this.editedUser.lastName?.trim()) {
      return false;
    }
    if (!this.editedUser.email?.trim() || !this.isValidEmail(this.editedUser.email)) {
      return false;
    }
    return true;
  }

  private isValidEmail(email: string): boolean {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }

  private isValidHubRole(role: UserRole): boolean {
    const hubRoles = [UserRole.DCB_ADMIN, UserRole.DCB_SUPPORT, UserRole.DCB_PARTNER];
    return hubRoles.includes(role);
  }

  // ==================== MÉTHODES UTILITAIRES ====================

  isCurrentUserProfile(): boolean {
    if (!this.user?.id) return false;
    return this.authService.isCurrentUserProfile(this.user.id);
  }

  getCreationDate(): string {
    if (!this.user?.createdTimestamp) return 'Non disponible';
    return this.formatTimestamp(this.user.createdTimestamp);
  }

  getLastLoginDate(): string {
    if (!this.user?.lastLogin) return 'Jamais connecté';
    return this.formatTimestamp(this.user.lastLogin);
  }

  getCreatorName(): string {
    if (!this.user?.createdByUsername) return 'Non disponible';
    return this.user.createdByUsername;
  }

  refresh() {
    this.loadUserProfile();
  }

  clearMessages() {
    this.error = '';
    this.success = '';
    this.cdRef.detectChanges();
  }

  // Méthodes pour le template
  getProfileTitle(): string {
    return 'Profil Utilisateur Hub';
  }

  getContextDescription(): string {
    return 'Gestion des utilisateurs de la plateforme DCB';
  }

  getAssignableRoles(): UserRole[] {
    const hubRoles = [UserRole.DCB_ADMIN, UserRole.DCB_SUPPORT, UserRole.DCB_PARTNER];
    return hubRoles.filter(role => this.roleService.canAssignRole(this.currentUserRole, role));
  }

  // Méthodes pour les actions spécifiques
  canChangeRole(): boolean {
    return this.canManageRoles() && !this.isCurrentUserProfile();
  }

  canToggleStatus(): boolean {
    return this.canEnableDisableUser() && !this.isCurrentUserProfile();
  }

  showRoleManagement(): boolean {
    return this.canManageRoles() && !this.isCurrentUserProfile();
  }
}