// src/app/core/services/role.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { jwtDecode } from 'jwt-decode';

interface DecodedToken {
  exp: number;
  sub?: string;
  preferred_username?: string;
  email?: string;
  given_name?: string;
  family_name?: string;
  resource_access?: {
    [key: string]: {
      roles: string[];
    };
  };
}

@Injectable({
  providedIn: 'root'
})
export class RoleService {
  private userRoles$ = new BehaviorSubject<string[]>(this.extractRolesFromToken());

  /**
   * Récupère les rôles actuels de l'utilisateur
   */
  getCurrentUserRoles(): string[] {
    return this.userRoles$.value;
  }

  /**
   * Observable des changements de rôles
   */
  onRolesChange(): Observable<string[]> {
    return this.userRoles$.asObservable();
  }

  /**
   * Rafraîchit les rôles depuis le token
   */
  refreshRoles(token?: string): void {
    const roles = this.extractRolesFromToken(token);
    this.userRoles$.next(roles);
  }

  // === VERIFICATIONS SPECIFIQUES ===

  isAdmin(): boolean {
    return this.hasRole('dcb-admin');
  }

  isPartner(): boolean {
    return this.hasRole('dcb-partner');
  }

  isSupport(): boolean {
    return this.hasRole('dcb-support');
  }

  isPartnerAdmin(): boolean {
    return this.hasRole('dcb-partner-admin');
  }

  isPartnerManager(): boolean {
    return this.hasRole('dcb-partner-merchant');
  }

  isPartnerSupport(): boolean {
    return this.hasRole('dcb-partner-support');
  }

  hasAnyRole(roles: string[]): boolean {
    const userRoles = this.getCurrentUserRoles();
    return roles.some(role => userRoles.includes(role));
  }

  hasAllRoles(roles: string[]): boolean {
    const userRoles = this.getCurrentUserRoles();
    return roles.every(role => userRoles.includes(role));
  }

  hasRole(role: string): boolean {
    return this.getCurrentUserRoles().includes(role);
  }

  // === METHODES PRIVEES ===

  private extractRolesFromToken(token?: string): string[] {
    const accessToken = token || localStorage.getItem('access_token');
    
    if (!accessToken) {
      return [];
    }

    try {
      const decoded: DecodedToken = jwtDecode(accessToken);
      
      if (decoded.resource_access) {
        const allRoles: string[] = [];
        
        Object.values(decoded.resource_access).forEach(client => {
          if (client?.roles) {
            allRoles.push(...client.roles);
          }
        });
        
        return [...new Set(allRoles)];
      }
      
      return [];
    } catch {
      return [];
    }
  }
}