// SDK-specific types that wrap and extend the lower-level package types into a unified, ergonomic API surface

import type {
  KeyPair,
  CovenantDocument,
  VerificationResult,
  VerificationCheck,
  Issuer,
  Beneficiary,
  ChainReference,
  EnforcementConfig,
  ProofConfig,
  RevocationConfig,
  CovenantMetadata,
  Obligation,
  PartyRole,
  CCLDocument,
  EvaluationResult as CCLEvaluationResult,
  Statement,
  Severity,
  AgentIdentity,
  ModelAttestation,
  DeploymentContext,
  LineageEntry,
} from '@nobulex/core';

// exports

/** Options for constructing a NobulexClient instance. */
export interface NobulexClientOptions {
  /** Optional pre-generated key pair for signing operations. */
  keyPair?: KeyPair;
  // Optional agent identifier for identity operations
  agentId?: string;
  /**
   * When true, the client will throw on verification failures
   * instead of returning a result with valid=false.
   */
  strictMode?: boolean;
  /** Optional key rotation policy for automatic key lifecycle management. */
  keyRotation?: {
    // Maximum key age in milliseconds before rotation is required
    maxAgeMs: number;
    /** Grace period in milliseconds where both old and new keys are valid. */
    overlapPeriodMs: number;
    /** Optional callback invoked when rotation occurs. */
    onRotation?: (oldKey: string, newKey: string) => void;
  };
}

// covenant creation

// Options for creating a new covenant through the SDK
export interface CreateCovenantOptions {
  /** The issuing party. */
  issuer: Issuer;
  /** The beneficiary party. */
  beneficiary: Beneficiary;
  /** CCL constraint source text. */
  constraints: string;
  /** Issuer's private key used to sign the document. If omitted, uses client keyPair. */
  privateKey?: Uint8Array;
  // Optional obligations
  obligations?: Obligation[];
  /** Optional chain reference to parent covenant. */
  chain?: ChainReference;
  /** Optional enforcement configuration. */
  enforcement?: EnforcementConfig;
  /** Optional proof configuration. */
  proof?: ProofConfig;
  // Optional revocation configuration
  revocation?: RevocationConfig;
  /** Optional metadata. */
  metadata?: CovenantMetadata;
  // Optional ISO 8601 expiry timestamp
  expiresAt?: string;
  /** Optional ISO 8601 activation timestamp. */
  activatesAt?: string;
}


/** Result of evaluating an action against a covenant's constraints. */
export interface EvaluationResult {
  // Whether the action is permitted
  permitted: boolean;
  /** The matched rule, if any. */
  matchedRule?: Statement;
  /** All matching statements. */
  allMatches: Statement[];
  /** Human-readable reason for the decision. */
  reason?: string;
  /** Severity of the matched rule. */
  severity?: Severity;
}

// identity

// Options for creating a new agent identity through the SDK
export interface CreateIdentityOptions {
  /** Operator key pair for signing. If omitted, uses client keyPair. */
  operatorKeyPair?: KeyPair;
  /** Optional human-readable operator identifier. */
  operatorIdentifier?: string;
  /** Model attestation describing the AI model. */
  model: ModelAttestation;
  // List of capabilities this agent has
  capabilities: string[];
  deployment: DeploymentContext;
}

/** Options for evolving an existing agent identity. */
export interface EvolveOptions {
  // Operator key pair for signing
  operatorKeyPair?: KeyPair;
  /** Type of change being made. */
  changeType: LineageEntry['changeType'];
  /** Human-readable description of the change. */
  description: string;
  // The fields being updated
  updates: {
    model?: ModelAttestation;
    capabilities?: string[];
    deployment?: DeploymentContext;
    operatorPublicKey?: string;
    operatorIdentifier?: string;
  };
  /** Optional explicit reputation carry-forward rate. */
  reputationCarryForward?: number;
}


/** Result of validating a chain of covenant documents. */
export interface ChainValidationResult {
  /** Whether the entire chain is valid. */
  valid: boolean;
  /** Per-document verification results, ordered from root to leaf. */
  results: VerificationResult[];
  /** Narrowing violations found between parent-child pairs. */
  narrowingViolations: NarrowingViolationEntry[];
}

/** A narrowing violation between a specific parent-child pair. */
export interface NarrowingViolationEntry {
  /** Index of the child document in the chain. */
  childIndex: number;
  /** Index of the parent document in the chain. */
  parentIndex: number;
  /** The narrowing violations found. */
  violations: Array<{
    childRule: Statement;
    parentRule: Statement;
    reason: string;
  }>;
}

// events

export type NobulexEventType =
  | 'covenant:created'
  | 'covenant:verified'
  | 'covenant:countersigned'
  | 'identity:created'
  | 'identity:evolved'
  | 'chain:resolved'
  | 'chain:validated'
  | 'evaluation:completed'
  | 'key:rotated';

/** Base event payload. */
export interface NobulexEvent {
  /** The event type. */
  type: NobulexEventType;
  /** ISO 8601 timestamp of when the event occurred. */
  timestamp: string;
}

// Event emitted when a covenant is created
export interface CovenantCreatedEvent extends NobulexEvent {
  type: 'covenant:created';
  document: CovenantDocument;
}

/** Event emitted when a covenant is verified. */
export interface CovenantVerifiedEvent extends NobulexEvent {
  type: 'covenant:verified';
  result: VerificationResult;
}

/** Event emitted when a covenant is countersigned. */
export interface CovenantCountersignedEvent extends NobulexEvent {
  type: 'covenant:countersigned';
  document: CovenantDocument;
  signerRole: PartyRole;
}

/** Event emitted when an identity is created. */
export interface IdentityCreatedEvent extends NobulexEvent {
  type: 'identity:created';
  identity: AgentIdentity;
}

// Event emitted when an identity is evolved
export interface IdentityEvolvedEvent extends NobulexEvent {
  type: 'identity:evolved';
  identity: AgentIdentity;
  changeType: LineageEntry['changeType'];
}

/** Event emitted when a chain is resolved. */
export interface ChainResolvedEvent extends NobulexEvent {
  type: 'chain:resolved';
  documents: CovenantDocument[];
}

/** Event emitted when a chain is validated. */
export interface ChainValidatedEvent extends NobulexEvent {
  type: 'chain:validated';
  result: ChainValidationResult;
}

/** Event emitted when an action is evaluated. */
export interface EvaluationCompletedEvent extends NobulexEvent {
  type: 'evaluation:completed';
  result: EvaluationResult;
  action: string;
  resource: string;
}

/** Event emitted when a key rotation occurs. */
export interface KeyRotatedEvent extends NobulexEvent {
  type: 'key:rotated';
  previousPublicKey: string;
  currentPublicKey: string;
}

/** Map of event types to their payloads. */
export interface NobulexEventMap {
  'covenant:created': CovenantCreatedEvent;
  'covenant:verified': CovenantVerifiedEvent;
  'covenant:countersigned': CovenantCountersignedEvent;
  'identity:created': IdentityCreatedEvent;
  'identity:evolved': IdentityEvolvedEvent;
  'chain:resolved': ChainResolvedEvent;
  'chain:validated': ChainValidatedEvent;
  'evaluation:completed': EvaluationCompletedEvent;
  'key:rotated': KeyRotatedEvent;
}

/** Event handler function type. */
export type NobulexEventHandler<T extends NobulexEventType> = (event: NobulexEventMap[T]) => void;



export type {
  KeyPair,
  CovenantDocument,
  VerificationResult,
  VerificationCheck,
  Issuer,
  Beneficiary,
  ChainReference,
  EnforcementConfig,
  ProofConfig,
  RevocationConfig,
  CovenantMetadata,
  Obligation,
  PartyRole,
  CCLDocument,
  CCLEvaluationResult,
  Statement,
  Severity,
  AgentIdentity,
  ModelAttestation,
  DeploymentContext,
  LineageEntry,
};
