import { Observable } from 'rxjs';
import { PartnerCredential, RegisterCredentialRequest } from '../models/partner-credential.model';
import { CreateNodeRequest, Environment, NodeStatus, ProvisioningNode } from '../models/provisioning-node.model';

/** Per docs/backend/PARTNER-PROVISIONING-API-CONTRACT.md §4, §6. */
export interface PartnerHierarchyGateway {
  /** Full tree for a company, with current statuses (§4.2). */
  loadHierarchy(companyId: string, environment: Environment): Observable<ProvisioningNode[]>;

  loadNode(nodeId: string): Observable<ProvisioningNode | null>;

  /** Resolve by the partner's own reference (§4.2). Null when unmatched - never a fuzzy match. */
  lookupByExternalReference(
    externalReference: string,
    environment: Environment,
  ): Observable<ProvisioningNode | null>;

  createProject(companyId: string, request: CreateNodeRequest): Observable<ProvisioningNode>;
  createStore(projectId: string, request: CreateNodeRequest): Observable<ProvisioningNode>;
  createPaymentPoint(storeId: string, request: CreateNodeRequest): Observable<ProvisioningNode>;

  /** 'active' | 'suspended' only - disabling is a separate, terminal call. */
  setStatus(nodeId: string, status: Extract<NodeStatus, 'active' | 'suspended'>, reason?: string): Observable<ProvisioningNode>;

  /** Terminal and cascading (§2). */
  disable(nodeId: string): Observable<ProvisioningNode>;

  loadCredentials(companyId: string): Observable<PartnerCredential[]>;
  registerCredential(request: RegisterCredentialRequest): Observable<PartnerCredential>;
  rotateCredential(keyId: string, newPublicKey: string): Observable<PartnerCredential>;
  revokeCredential(keyId: string): Observable<void>;
}
