import { Injectable, computed, inject } from '@angular/core';
import { RemoteData, fromResource } from '@shared/application/remote-data';
import { Capability } from '@shared/domain/capability';
import { MeAdapter, parseMe } from '@shared/infrastructure/me.adapter';

type Err = Error | undefined;

/**
 * The current principal's capabilities (PRD-0002 §6) — one root singleton, like
 * `SessionStore`/`BigProfileStore`. Global capabilities load once from `GET /me`;
 * a screen's own decision DTO (e.g. `BriefViewDto.decisions`) covers anything tied
 * to a specific resource's live status — no extra round-trip needed for that.
 *
 * `can()` is deny-by-default: loading, failed, or an unrecognized capability all
 * resolve to `false`. This store never derives a capability from a role — it only
 * mirrors what the server already resolved.
 */
@Injectable({ providedIn: 'root' })
export class AccessStore {
  private adapter = inject(MeAdapter);
  private meRes = this.adapter.meResource();

  private capabilities = computed<RemoteData<Err, Capability[]>>(() => {
    const rd = fromResource(this.meRes);
    if (rd.tag !== 'Success') return rd;
    const parsed = parseMe(rd.value);
    return parsed.ok
      ? { tag: 'Success', value: parsed.value }
      : { tag: 'Failure', error: new Error(parsed.error) };
  });

  can(capability: Capability): boolean {
    const rd = this.capabilities();
    return rd.tag === 'Success' && rd.value.includes(capability);
  }
}
