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

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

import { MerchantUsersService } from '../merchant-users.service';
import { RoleManagementService } from '@core/services/hub-users-roles-management.service';
import { AuthService } from '@core/services/auth.service';
import { UiCard } from '@app/components/ui-card';

@Component({
  selector: 'app-merchant-users-list',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    NgIcon,
    UiCard, 
    NgbPaginationModule
  ],
  templateUrl: './merchant-users-list.html',
})
export class MerchantUsersList implements OnInit, OnDestroy {
  private authService = inject(AuthService);
  private merchantUsersService = inject(MerchantUsersService);
  protected roleService = inject(RoleManagementService);
  private cdRef = inject(ChangeDetectorRef);
  private destroy$ = new Subject<void>();
  
  // Configuration
  readonly UserRole = UserRole;
  readonly UserType = UserType;
  readonly UserUtils = UserUtils;
  
  // Inputs
  @Input() canCreateUsers: boolean = false;
  @Input() canDeleteUsers: boolean = false;

  // Outputs
  
  @Output() userSelected = new EventEmitter<string>();
  @Output() openCreateUserModal = new EventEmitter<void>();
  @Output() resetPasswordRequested = new EventEmitter<string>();
  @Output() deleteUserRequested = new EventEmitter<string>();

  // Données
  allUsers: User[] = [];
  filteredUsers: User[] = [];
  displayedUsers: User[] = [];
  
  // États
  loading = false;
  error = '';

  // Recherche et filtres
  searchTerm = '';
  statusFilter: 'all' | 'enabled' | 'disabled' = 'all';
  emailVerifiedFilter: 'all' | 'verified' | 'not-verified' = 'all';
  roleFilter: UserRole | 'all' = 'all';

  // Pagination
  currentPage = 1;
  itemsPerPage = 10;
  totalItems = 0;
  totalPages = 0;

  // Tri
  sortField: keyof User = 'username';
  sortDirection: 'asc' | 'desc' = 'asc';

  // Rôles disponibles pour le filtre
  availableRoles: { value: UserRole | 'all'; label: string, description: string  }[] = [];

  // ID du merchant partner courant et permissions
  currentMerchantPartnerId: string = '';
  currentUserRole: UserRole | null = null;
  canViewAllMerchants = false;

  // Getters pour la logique conditionnelle
  get showMerchantPartnerColumn(): boolean {
    return this.canViewAllMerchants;
  }

  get showCreateButton(): boolean {
    return this.canCreateUsers;
  }

  get showDeleteButton(): boolean {
    return this.canDeleteUsers;
  }

  ngOnInit() {
    this.loadCurrentUserPermissions();
    this.initializeAvailableRoles();
  }

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

  private loadCurrentUserPermissions() {
    this.authService.getUserProfile()
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (user) => {
          this.currentUserRole = this.extractUserRole(user);
          this.currentMerchantPartnerId = this.extractMerchantPartnerId(user);
          this.canViewAllMerchants = this.canViewAllMerchantsCheck(this.currentUserRole);

          console.log('Merchant User Context Loaded:', {
            role: this.currentUserRole,
            merchantPartnerId: this.currentMerchantPartnerId,
            canViewAllMerchants: this.canViewAllMerchants
          });

          this.loadUsers();
        },
        error: (error) => {
          console.error('Error loading current user permissions:', error);
          this.fallbackPermissions();
          this.loadUsers();
        }
      });
  }

  private extractUserRole(user: any): UserRole | null {
    const userRoles = this.authService.getCurrentUserRoles();
    if (userRoles && userRoles.length > 0) {
      return userRoles[0];
    }
    return null;
  }

  private extractMerchantPartnerId(user: any): string {
    if (user?.merchantPartnerId) {
      return user.merchantPartnerId;
    }
    return this.authService.getCurrentMerchantPartnerId() || '';
  }

  private canViewAllMerchantsCheck(role: UserRole | null): boolean {
    if (!role) return false;
    
    const canViewAllRoles = [
      UserRole.DCB_ADMIN,
      UserRole.DCB_SUPPORT,
      UserRole.DCB_PARTNER_ADMIN
    ];
    
    return canViewAllRoles.includes(role);
  }

  private fallbackPermissions(): void {
    this.currentUserRole = this.authService.getCurrentUserRole();
    this.currentMerchantPartnerId = this.authService.getCurrentMerchantPartnerId() || '';
    this.canViewAllMerchants = this.canViewAllMerchantsCheck(this.currentUserRole);
  }

  private initializeAvailableRoles() {
    this.availableRoles = [
      { value: 'all', label: 'Tous les rôles', description: 'Tous les Roles'  },
      { value: UserRole.DCB_PARTNER_ADMIN, label: 'DCB Partner Admin', description: 'Admin Partenaire commercial' },
      { value: UserRole.DCB_PARTNER_MANAGER, label: 'DCB Partner Manager', description: 'Manager Partenaire commercial' },
      { value: UserRole.DCB_PARTNER_SUPPORT, label: 'DCB Partner Support', description: 'Support Partenaire commercial' }
    ];
  }

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

    let usersObservable: Observable<User[]>;

    if (this.canViewAllMerchants) {
      // Admin/Support accédant au contexte Merchant
      usersObservable = this.merchantUsersService.getMerchantUsers(this.currentPage, this.itemsPerPage).pipe(
        map((response: PaginatedUserResponse) => response.users)
      );
    } else if (this.currentMerchantPartnerId) {
      // Merchant régulier voyant son équipe
      usersObservable = this.merchantUsersService.getMerchantUsersByPartner(this.currentMerchantPartnerId);
    } else {
      // Fallback
      usersObservable = this.merchantUsersService.getMyMerchantUsers();
    }
  
    usersObservable
      .pipe(
        takeUntil(this.destroy$),
        catchError(error => {
          console.error('Error loading merchant users:', error);
          this.error = 'Erreur lors du chargement des utilisateurs marchands';
          return of([] as User[]);
        })
      )
      .subscribe({
        next: (users) => {
          this.allUsers = users || [];
          console.log(`✅ Loaded ${this.allUsers.length} merchant users`);
          this.applyFiltersAndPagination();
          this.loading = false;
          this.cdRef.detectChanges();
        },
        error: () => {
          this.error = 'Erreur lors du chargement des utilisateurs marchands';
          this.loading = false;
          this.allUsers = [];
          this.filteredUsers = [];
          this.displayedUsers = [];
          this.cdRef.detectChanges();
        }
      });
  }

  // Recherche et filtres
  onSearch() {
    this.currentPage = 1;
    this.applyFiltersAndPagination();
  }

  onClearFilters() {
    this.searchTerm = '';
    this.statusFilter = 'all';
    this.emailVerifiedFilter = 'all';
    this.roleFilter = 'all';
    this.currentPage = 1;
    this.applyFiltersAndPagination();
  }

  applyFiltersAndPagination() {
    if (!this.allUsers) {
      this.allUsers = [];
    }

    // Appliquer les filtres
    this.filteredUsers = this.allUsers.filter(user => {
      const matchesSearch = !this.searchTerm || 
        user.username.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
        user.email.toLowerCase().includes(this.searchTerm.toLowerCase()) ||
        (user.firstName && user.firstName.toLowerCase().includes(this.searchTerm.toLowerCase())) ||
        (user.lastName && user.lastName.toLowerCase().includes(this.searchTerm.toLowerCase()));

      const matchesStatus = this.statusFilter === 'all' || 
        (this.statusFilter === 'enabled' && user.enabled) ||
        (this.statusFilter === 'disabled' && !user.enabled);

      const matchesEmailVerified = this.emailVerifiedFilter === 'all' ||
        (this.emailVerifiedFilter === 'verified' && user.emailVerified) ||
        (this.emailVerifiedFilter === 'not-verified' && !user.emailVerified);

      const matchesRole = this.roleFilter === 'all' || 
        (user.role && user.role.includes(this.roleFilter));

      return matchesSearch && matchesStatus && matchesEmailVerified && matchesRole;
    });

    // Appliquer le tri
    this.filteredUsers.sort((a, b) => {
      const aValue = a[this.sortField];
      const bValue = b[this.sortField];
      
      if (aValue === bValue) return 0;
      
      let comparison = 0;
      if (typeof aValue === 'string' && typeof bValue === 'string') {
        comparison = aValue.localeCompare(bValue);
      } else if (typeof aValue === 'number' && typeof bValue === 'number') {
        comparison = aValue - bValue;
      } else if (typeof aValue === 'boolean' && typeof bValue === 'boolean') {
        comparison = (aValue === bValue) ? 0 : aValue ? -1 : 1;
      }
      
      return this.sortDirection === 'asc' ? comparison : -comparison;
    });

    // Calculer la pagination
    this.totalItems = this.filteredUsers.length;
    this.totalPages = Math.ceil(this.totalItems / this.itemsPerPage);
    
    // Appliquer la pagination
    const startIndex = (this.currentPage - 1) * this.itemsPerPage;
    const endIndex = startIndex + this.itemsPerPage;
    this.displayedUsers = this.filteredUsers.slice(startIndex, endIndex);
  }

  // Tri
  sort(field: keyof User) {
    if (this.sortField === field) {
      this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
    } else {
      this.sortField = field;
      this.sortDirection = 'asc';
    }
    this.applyFiltersAndPagination();
  }

  getSortIcon(field: string): string {
    if (this.sortField !== field) return 'lucideArrowUpDown';
    return this.sortDirection === 'asc' ? 'lucideArrowUp' : 'lucideArrowDown';
  }

  // Pagination
  onPageChange(page: number) {
    this.currentPage = page;
    this.applyFiltersAndPagination();
  }

  getStartIndex(): number {
    return (this.currentPage - 1) * this.itemsPerPage + 1;
  }

  getEndIndex(): number {
    return Math.min(this.currentPage * this.itemsPerPage, this.totalItems);
  }

  // Actions
  viewUserProfile(userId: string) {
    this.userSelected.emit(userId);
  }

  resetPassword(user: User) {
    this.resetPasswordRequested.emit(user.id);
  }

  deleteUser(user: User) {
    this.deleteUserRequested.emit(user.id);
  }

  enableUser(user: User) {
    this.merchantUsersService.enableMerchantUser(user.id)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (updatedUser) => {
          const index = this.allUsers.findIndex(u => u.id === user.id);
          if (index !== -1) {
            this.allUsers[index] = updatedUser;
          }
          this.applyFiltersAndPagination();
          this.cdRef.detectChanges();
        },
        error: (error) => {
          console.error('Error enabling merchant user:', error);
          this.error = 'Erreur lors de l\'activation de l\'utilisateur';
          this.cdRef.detectChanges();
        }
      });
  }

  disableUser(user: User) {
    this.merchantUsersService.disableMerchantUser(user.id)
      .pipe(takeUntil(this.destroy$))
      .subscribe({
        next: (updatedUser) => {
          const index = this.allUsers.findIndex(u => u.id === user.id);
          if (index !== -1) {
            this.allUsers[index] = updatedUser;
          }
          this.applyFiltersAndPagination();
          this.cdRef.detectChanges();
        },
        error: (error) => {
          console.error('Error disabling merchant user:', error);
          this.error = 'Erreur lors de la désactivation de l\'utilisateur';
          this.cdRef.detectChanges();
        }
      });
  }

  // Utilitaires d'affichage
  getStatusBadgeClass(user: User): string {
    if (!user.enabled) return 'badge bg-danger';
    if (!user.emailVerified) return 'badge bg-warning';
    return 'badge bg-success';
  }

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

  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';
  }

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

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

  getUserDisplayName(user: User): string {
    if (user.firstName && user.lastName) {
      return `${user.firstName} ${user.lastName}`;
    }
    return user.username;
  }

  getEnabledUsersCount(): number {
    return this.allUsers.filter(user => user.enabled).length;
  }

  getDisabledUsersCount(): number {
    return this.allUsers.filter(user => !user.enabled).length;
  }

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

  // Recherche rapide par rôle
  filterByRole(role: UserRole | 'all') {
    this.roleFilter = role;
    this.currentPage = 1;
    this.applyFiltersAndPagination();
  }

  // Recharger les données
  refreshData() {
    this.loadUsers();
  }

  // Méthodes pour le template
  getCardTitle(): string {
    return 'Équipe Marchande';
  }

  getHelperText(): string {
    return this.canViewAllMerchants 
      ? 'Vue administrative - Tous les utilisateurs marchands' 
      : 'Votre équipe marchande';
  }

  getHelperIcon(): string {
    return this.canViewAllMerchants ? 'lucideShield' : 'lucideUsers';
  }

  // Méthode pour compter les utilisateurs par rôle
  getUsersCountByRole(role: UserRole): number {
    if (!this.allUsers || this.allUsers.length === 0) return 0;
    
    return this.allUsers.filter(user => 
      user.role && user.role.includes(role)
    ).length;
  }

  getLoadingText(): string {
    return 'Chargement des utilisateurs marchands...';
  }

  getEmptyStateTitle(): string {
    return 'Aucun utilisateur marchand trouvé';
  }

  getEmptyStateDescription(): string {
    return 'Aucun utilisateur ne correspond à vos critères de recherche.';
  }

  getEmptyStateButtonText(): string {
    return 'Créer le premier utilisateur';
  }

  getColumnCount(): number {
    return this.showMerchantPartnerColumn ? 7 : 6;
  }

  showMerchantPartnerId(): boolean {
    return !this.canViewAllMerchants;
  }

  // Statistiques
  getTotalUsersCount(): number {
    return this.allUsers.length;
  }

  getActiveUsersCount(): number {
    return this.allUsers.filter(user => user.enabled).length;
  }

  getVerifiedUsersCount(): number {
    return this.allUsers.filter(user => user.emailVerified).length;
  }
}