/**
 * Agent Receipt schema types.
 *
 * These types model the Agent Receipt as a W3C Verifiable Credential.
 * Both the full and minimal receipt variants share the same type — optional
 * fields are marked with `?`.
 */

export const CONTEXT = [
	"https://www.w3.org/ns/credentials/v2",
	"https://agentreceipts.ai/context/v1",
] as const;

export const CREDENTIAL_TYPE = [
	"VerifiableCredential",
	"AgentReceipt",
] as const;

export const VERSION = "0.2.0";

// --- Risk levels ---

export type RiskLevel = "low" | "medium" | "high" | "critical";

// --- Outcome status ---

export type OutcomeStatus = "success" | "failure" | "pending";

// --- Issuer ---

export interface Operator {
	id: string;
	name: string;
}

export interface Issuer {
	id: string;
	type?: string;
	name?: string;
	operator?: Operator;
	model?: string;
	session_id?: string;
}

// --- Principal ---

export interface Principal {
	id: string;
	type?: string;
}

// --- Action ---

export interface ActionTarget {
	system: string;
	resource?: string;
}

export interface Action {
	id: string;
	type: string;
	tool_name?: string;
	risk_level: RiskLevel;
	target?: ActionTarget;
	parameters_hash?: string;
	/**
	 * Operator-controlled, additive disclosure of parameter values for audit display.
	 * SAFETY: callers MUST restrict keys to an explicit operator-managed allowlist.
	 * Never populate from raw arguments — receipts are signed and durable, and any
	 * value placed here is permanent. The SDK does not auto-populate or validate
	 * this field; enforcement lives outside the SDK. Taxonomy-level allowlist
	 * support is tracked in
	 * {@link https://github.com/agent-receipts/ar/issues/258 | #258}.
	 * `parameters_hash` remains the cryptographic commitment to the full payload.
	 *
	 * Renamed from `parameters_preview` in 0.6.0 per
	 * {@link https://github.com/agent-receipts/ar/blob/main/docs/adr/0012-payload-disclosure-policy.md | ADR-0012}
	 * — "preview" misdescribed a permanent, signed field. No deprecation alias
	 * is provided; pre-1.0 callers must update field names.
	 */
	parameters_disclosure?: Record<string, string>;
	timestamp: string;
	trusted_timestamp?: string;
}

// --- Intent ---

export interface Intent {
	conversation_hash?: string;
	prompt_preview?: string;
	prompt_preview_truncated?: boolean;
	reasoning_hash?: string;
}

// --- Outcome ---

export interface StateChange {
	before_hash: string;
	after_hash: string;
}

export interface Outcome {
	status: OutcomeStatus;
	error?: string;
	reversible?: boolean;
	reversal_method?: string;
	reversal_window_seconds?: number;
	state_change?: StateChange;
	/** SHA-256 hash of the RFC 8785 canonical JSON of the server's response,
	 *  computed after secret redaction (redact → hash → sign). */
	response_hash?: string;
}

// --- Authorization ---

export interface Authorization {
	scopes: string[];
	granted_at: string;
	expires_at?: string;
	grant_ref?: string;
}

// --- Chain ---

export interface Chain {
	sequence: number;
	previous_receipt_hash: string | null;
	chain_id: string;
	/** When present, MUST be true. Marks this as the final receipt in the chain.
	 *  Explicit false is not valid — use absence to express "no claim". */
	terminal?: true;
}

// --- Credential Subject ---

export interface CredentialSubject {
	principal: Principal;
	action: Action;
	intent?: Intent;
	outcome: Outcome;
	authorization?: Authorization;
	chain: Chain;
}

// --- Proof ---

export interface Proof {
	type: string;
	created?: string;
	verificationMethod?: string;
	proofPurpose?: string;
	proofValue: string;
}

// --- Agent Receipt ---

export interface AgentReceipt {
	"@context": readonly string[];
	id: string;
	type: readonly string[];
	version: string;
	issuer: Issuer;
	issuanceDate: string;
	credentialSubject: CredentialSubject;
	proof: Proof;
}

/**
 * An Agent Receipt before signing — no proof field yet.
 */
export type UnsignedAgentReceipt = Omit<AgentReceipt, "proof">;
