import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { AUTH_BFF_BASE_URL } from 'feature-auth';
import type { Observable } from 'rxjs';

/**
 * One scope row as the SPA sees it — mirror of `UserScopeDto` on
 * the BFF side. ISO-string timestamps; the SPA never round-trips
 * `Date` instances per the audit-page convention.
 */
export interface UserScope {
  readonly id: string;
  readonly kind: string;
  readonly value: string;
  readonly source: string;
  readonly createdAt: string;
  readonly expiresAt: string | null;
}

export interface UserScopesPayload {
  readonly user: {
    readonly oid: string;
    readonly userId: string;
    readonly displayName: string;
    readonly email: string | null;
  };
  readonly scopes: ReadonlyArray<UserScope>;
}

export interface GrantUserScopeInput {
  readonly kind: string;
  readonly value?: string;
  readonly expiresAt?: string;
}

/**
 * `UserScopesService` — Thin HttpClient wrapper around
 * `/api/admin/users/:oid/scopes`. Same shape convention as
 * `AdminUsersService` — `providedIn: 'root'` because the single
 * consumer is the `UserScopesPayload`.
 */
@Injectable({ providedIn: 'root' })
export class UserScopesService {
  private readonly http = inject(HttpClient);
  private readonly bffBaseUrl = inject(AUTH_BFF_BASE_URL);

  list(oid: string): Observable<UserScopesPayload> {
    return this.http.get<UserScopesPayload>(
      `${this.bffBaseUrl}/admin/users/${encodeURIComponent(oid)}/scopes`,
    );
  }

  grant(oid: string, input: GrantUserScopeInput): Observable<UserScope> {
    return this.http.post<UserScope>(
      `${this.bffBaseUrl}/admin/users/${encodeURIComponent(oid)}/scopes`,
      input,
    );
  }

  revoke(oid: string, scopeId: string): Observable<void> {
    return this.http.delete<void>(
      `${this.bffBaseUrl}/admin/users/${encodeURIComponent(oid)}/scopes/${encodeURIComponent(scopeId)}`,
    );
  }
}
