// src/app/modules/users/services/users.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { environment } from '@environments/environment';
import { Observable, map, catchError, throwError, of } from 'rxjs';
import { AvailableRolesResponse } from '@core/services/role-management.service';
// Interfaces alignées avec le contrôleur NestJS
export interface HubUserResponse {
  id: string;
  username: string;
  email: string;
  firstName: string;
  lastName: string;
  role: UserRole;
  enabled: boolean;
  emailVerified: boolean;
  createdBy: string;
  createdByUsername: string;
  createdTimestamp: number;
  lastLogin?: number;
  userType: 'HUB';
}

export interface CreateHubUserDto {
  username: string;
  email: string;
  firstName: string;
  lastName: string;
  password: string;
  role: UserRole;
  enabled?: boolean;
  emailVerified?: boolean;
}

export interface UpdateHubUserDto {
  firstName?: string;
  lastName?: string;
  email?: string;
  enabled?: boolean;
}

export interface ResetPasswordDto {
  newPassword: string;
  temporary?: boolean;
}

export interface PaginatedUserResponse {
  users: HubUserResponse[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export enum UserRole {
  DCB_ADMIN = 'dcb-admin',
  DCB_SUPPORT = 'dcb-support',
  DCB_PARTNER = 'dcb-partner'
}

@Injectable({ providedIn: 'root' })
export class HubUsersService {
  private http = inject(HttpClient);
  private apiUrl = `${environment.iamApiUrl}/hub-users`;

  // === CRUD COMPLET ===

  /**
   * Crée un nouvel utilisateur Hub
   */
  createUser(createUserDto: CreateHubUserDto): Observable<HubUserResponse> {
    // Validation
    if (!createUserDto.username?.trim()) {
      return throwError(() => 'Username is required and cannot be empty');
    }

    if (!createUserDto.email?.trim()) {
      return throwError(() => 'Email is required and cannot be empty');
    }

    if (!createUserDto.password || createUserDto.password.length < 8) {
      return throwError(() => 'Password must be at least 8 characters');
    }

    if (!createUserDto.role) {
      return throwError(() => 'Role is required');
    }

    // Nettoyage des données
    const payload = {
      username: createUserDto.username.trim(),
      email: createUserDto.email.trim(),
      firstName: (createUserDto.firstName || '').trim(),
      lastName: (createUserDto.lastName || '').trim(),
      password: createUserDto.password,
      role: createUserDto.role,
      enabled: createUserDto.enabled !== undefined ? createUserDto.enabled : true,
      emailVerified: createUserDto.emailVerified !== undefined ? createUserDto.emailVerified : false,
    };

    return this.http.post<HubUserResponse>(this.apiUrl, payload).pipe(
      catchError(error => throwError(() => error))
    );
  }

  /**
   * Récupère tous les utilisateurs Hub avec pagination
   */
  findAllUsers(page: number = 1, limit: number = 10, filters?: any): Observable<PaginatedUserResponse> {
    let params = new HttpParams()
      .set('page', page.toString())
      .set('limit', limit.toString());

    if (filters) {
      Object.keys(filters).forEach(key => {
        if (filters[key] !== undefined && filters[key] !== null) {
          params = params.set(key, filters[key].toString());
        }
      });
    }

    return this.http.get<HubUserResponse[]>(this.apiUrl, { params, observe: 'response' }).pipe(
      map(response => {
        const users = response.body || [];
        const total = parseInt(response.headers.get('X-Total-Count') || '0');
        
        return {
          users,
          total,
          page,
          limit,
          totalPages: Math.ceil(total / limit)
        };
      }),
      catchError(error => {
        console.error('Error loading users:', error);
        return throwError(() => error);
      })
    );
  }

  /**
   * Récupère tous les utilisateurs Hub avec pagination
   */
  findAllMerchantUsers(page: number = 1, limit: number = 10, filters?: any): Observable<PaginatedUserResponse> {
    let params = new HttpParams()
      .set('page', page.toString())
      .set('limit', limit.toString());

    if (filters) {
      Object.keys(filters).forEach(key => {
        if (filters[key] !== undefined && filters[key] !== null) {
          params = params.set(key, filters[key].toString());
        }
      });
    }

    return this.http.get<HubUserResponse[]>(`${this.apiUrl}//merchants/all`, { params, observe: 'response' }).pipe(
      map(response => {
        const users = response.body || [];
        const total = parseInt(response.headers.get('X-Total-Count') || '0');
        
        return {
          users,
          total,
          page,
          limit,
          totalPages: Math.ceil(total / limit)
        };
      }),
      catchError(error => {
        console.error('Error loading users:', error);
        return throwError(() => error);
      })
    );
  }

  /**
   * Récupère un utilisateur Hub par ID
   */
  getUserById(id: string): Observable<HubUserResponse> {
    return this.http.get<HubUserResponse>(`${this.apiUrl}/${id}`);
  }

  /**
   * Met à jour un utilisateur Hub
   */
  updateUser(id: string, updateUserDto: UpdateHubUserDto): Observable<HubUserResponse> {
    return this.http.put<HubUserResponse>(`${this.apiUrl}/${id}`, updateUserDto);
  }

  /**
   * Supprime un utilisateur Hub
   */
  deleteUser(id: string): Observable<{ message: string }> {
    return this.http.delete<{ message: string }>(`${this.apiUrl}/${id}`);
  }

  // === GESTION DES MOTS DE PASSE ===

  /**
   * Réinitialise le mot de passe d'un utilisateur
   */
  resetPassword(userId: string, newPassword: string, temporary: boolean = true): Observable<{ message: string }> {
    return this.http.post<{ message: string }>(
      `${this.apiUrl}/${userId}/reset-password`,
      { newPassword, temporary }
    );
  }

  /**
   * Envoie un email de réinitialisation de mot de passe
   */
  sendPasswordResetEmail(userId: string): Observable<{ message: string }> {
    return this.http.post<{ message: string }>(
      `${this.apiUrl}/${userId}/send-reset-email`,
      {}
    );
  }

  // === GESTION DU STATUT ===

  /**
   * Active un utilisateur
   */
  enableUser(id: string): Observable<HubUserResponse> {
    return this.http.put<HubUserResponse>(`${this.apiUrl}/${id}`, { enabled: true });
  }

  /**
   * Désactive un utilisateur
   */
  disableUser(id: string): Observable<HubUserResponse> {
    return this.http.put<HubUserResponse>(`${this.apiUrl}/${id}`, { enabled: false });
  }

  // === GESTION DES RÔLES ===

  /**
   * Met à jour le rôle d'un utilisateur
   */
  updateUserRole(id: string, role: UserRole): Observable<HubUserResponse> {
    return this.http.put<HubUserResponse>(`${this.apiUrl}/${id}/role`, { role });
  }

  /**
   * Récupère les rôles Hub disponibles
   */
  getAvailableHubRoles(): Observable<AvailableRolesResponse> {
    return this.http.get<AvailableRolesResponse>(
      `${this.apiUrl}/roles/available`
    ).pipe(
      catchError(error => {
        console.error('Error loading available roles:', error);
        // Fallback en cas d'erreur
        return of({
          roles: [
            {
              value: UserRole.DCB_ADMIN,
              label: 'DCB Admin',
              description: 'Full administrative access to the entire system'
            },
            {
              value: UserRole.DCB_SUPPORT,
              label: 'DCB Support',
              description: 'Support access with limited administrative capabilities'
            },
            {
              value: UserRole.DCB_PARTNER,
              label: 'DCB Partner',
              description: 'Merchant partner with access to their own merchant ecosystem'
            }
          ]
        });
      })
    );
  }

  /**
   * Récupère les utilisateurs par rôle
   */
  getUsersByRole(role: UserRole): Observable<HubUserResponse[]> {
    return this.http.get<HubUserResponse[]>(`${this.apiUrl}/role/${role}`);
  }
  
  // === STATISTIQUES ===

  /**
   * Récupère les statistiques des utilisateurs
   */
  getUsersStats(): Observable<any> {
    return this.http.get<any>(`${this.apiUrl}/stats/overview`);
  }

  // === UTILITAIRES ===

  /**
   * Vérifie si un nom d'utilisateur existe
   */
  userExists(username: string): Observable<{ exists: boolean }> {
    // Implémentation temporaire - à adapter selon votre API
    return this.findAllUsers().pipe(
      map(response => ({
        exists: response.users.some(user => user.username === username)
      }))
    );
  }

  /**
   * Recherche des utilisateurs
   */
  searchUsers(query: string): Observable<HubUserResponse[]> {
    return this.findAllUsers().pipe(
      map(response => response.users.filter(user => 
        user.username.toLowerCase().includes(query.toLowerCase()) ||
        user.email.toLowerCase().includes(query.toLowerCase()) ||
        user.firstName?.toLowerCase().includes(query.toLowerCase()) ||
        user.lastName?.toLowerCase().includes(query.toLowerCase())
      ))
    );
  }
}