/**
 * Shared TypeScript interfaces and types for SentryAgent.ai AgentIdP.
 * All interfaces and types live here — no inline type definitions in service/controller files.
 */

// ============================================================================
// Enumerations / Union Types
// ============================================================================

/** Functional classification of an AI agent. */
export type AgentType =
  | 'screener'
  | 'classifier'
  | 'orchestrator'
  | 'extractor'
  | 'summarizer'
  | 'router'
  | 'monitor'
  | 'custom';

/** Lifecycle status of an AI agent. */
export type AgentStatus = 'active' | 'suspended' | 'decommissioned';

/** Target deployment environment for an agent. */
export type DeploymentEnv = 'development' | 'staging' | 'production';

/** Lifecycle status of an agent credential. */
export type CredentialStatus = 'active' | 'revoked';

/** OAuth 2.0 scope values supported by this IdP. */
export type OAuthScope =
  | 'agents:read'
  | 'agents:write'
  | 'tokens:read'
  | 'audit:read'
  | 'admin:orgs'
  | 'webhooks:read'
  | 'webhooks:write';

/** Audit action identifiers for all significant platform events. */
export type AuditAction =
  | 'agent.created'
  | 'agent.updated'
  | 'agent.decommissioned'
  | 'agent.suspended'
  | 'agent.reactivated'
  | 'token.issued'
  | 'token.revoked'
  | 'token.introspected'
  | 'credential.generated'
  | 'credential.rotated'
  | 'credential.revoked'
  | 'auth.failed'
  | 'org.created'
  | 'org.updated'
  | 'org.deleted'
  | 'org.member_added'
  | 'webhook.created'
  | 'webhook.updated'
  | 'webhook.deleted'
  | 'delegation.created'
  | 'delegation.verified'
  | 'delegation.revoked'
  | 'scaffold.generated';

/** Outcome of an audited action. */
export type AuditOutcome = 'success' | 'failure';

// ============================================================================
// Agent Registry
// ============================================================================

/** Full representation of a registered AI agent identity. */
export interface IAgent {
  agentId: string;
  organizationId: string;
  email: string;
  agentType: AgentType;
  version: string;
  capabilities: string[];
  owner: string;
  deploymentEnv: DeploymentEnv;
  status: AgentStatus;
  /** Whether this agent is listed in the public marketplace. Defaults to false. */
  isPublic: boolean;
  createdAt: Date;
  updatedAt: Date;
  /** W3C DID identifier for this agent. Populated after DID generation. */
  did?: string;
  /** Timestamp when the DID was first generated for this agent. */
  didCreatedAt?: Date;
}

/** Request body for registering a new AI agent. */
export interface ICreateAgentRequest {
  email: string;
  agentType: AgentType;
  version: string;
  capabilities: string[];
  owner: string;
  deploymentEnv: DeploymentEnv;
  organizationId?: string;
}

/** Request body for partially updating an agent. */
export interface IUpdateAgentRequest {
  agentType?: AgentType;
  version?: string;
  capabilities?: string[];
  owner?: string;
  deploymentEnv?: DeploymentEnv;
  status?: AgentStatus;
  /** Set to true to list this agent in the public marketplace. */
  isPublic?: boolean;
}

// ============================================================================
// Agent Marketplace
// ============================================================================

/** Query filters for the public agent marketplace listing. */
export interface IMarketplaceFilters {
  /** Full-text search across owner, capabilities, and agent type. */
  q?: string;
  /** Filter by a specific capability string. */
  capability?: string;
  /** Filter by owner (publisher). */
  publisher?: string;
  page: number;
  limit: number;
}

/** Minimal W3C DID Document returned with marketplace agent detail. */
export interface IMinimalDIDDocument {
  '@context': string[];
  id: string;
  controller: string;
  verificationMethod: unknown[];
  authentication: unknown[];
}

/** Agent card returned by the marketplace detail endpoint. */
export interface IMarketplaceAgentCard {
  agentId: string;
  agentType: AgentType;
  version: string;
  capabilities: string[];
  owner: string;
  deploymentEnv: DeploymentEnv;
  did: string | null;
  didDocument: IMinimalDIDDocument | null;
  publishedAt: Date;
}

/** Paginated marketplace listing response. */
export interface IPaginatedMarketplaceResponse {
  data: IMarketplaceAgentCard[];
  total: number;
  page: number;
  limit: number;
}

/** Paginated list of agents. */
export interface IPaginatedAgentsResponse {
  data: IAgent[];
  total: number;
  page: number;
  limit: number;
}

/** Query filters for listing agents. */
export interface IAgentListFilters {
  owner?: string;
  agentType?: AgentType;
  status?: AgentStatus;
  page: number;
  limit: number;
}

// ============================================================================
// Credentials
// ============================================================================

/** A credential record for an AI agent (clientSecret never included). */
export interface ICredential {
  credentialId: string;
  clientId: string;
  status: CredentialStatus;
  createdAt: Date;
  expiresAt: Date | null;
  revokedAt: Date | null;
}

/** Credential with the plain-text secret — returned once only on create/rotate. */
export interface ICredentialWithSecret extends ICredential {
  clientSecret: string;
}

/** Database row for a credential, including the bcrypt hash and optional Vault path. */
export interface ICredentialRow extends ICredential {
  /** bcrypt hash of the secret — populated for Phase 1 (bcrypt-only) credentials. */
  secretHash: string;
  /**
   * Vault KV v2 data path for this credential.
   * When present, the secret is stored in Vault and secretHash is an empty placeholder.
   * When null, bcrypt verification via secretHash is used (Phase 1 behaviour).
   */
  vaultPath: string | null;
}

/** Request body for generating or rotating a credential. */
export interface IGenerateCredentialRequest {
  expiresAt?: string | Date;
}

/** Paginated list of credentials. */
export interface IPaginatedCredentialsResponse {
  data: ICredential[];
  total: number;
  page: number;
  limit: number;
}

/** Query filters for listing credentials. */
export interface ICredentialListFilters {
  status?: CredentialStatus;
  page: number;
  limit: number;
}

// ============================================================================
// OAuth2 Token
// ============================================================================

/** JWT access token payload (claims). */
export interface ITokenPayload {
  /** Subject — agentId. */
  sub: string;
  /** client_id — agentId. */
  client_id: string;
  /** Space-separated OAuth 2.0 scopes. */
  scope: string;
  /** JWT ID — UUID v4. */
  jti: string;
  /** Issued at (Unix seconds). */
  iat: number;
  /** Expiry (Unix seconds). */
  exp: number;
  /** Organization the agent belongs to (optional for backward compat). */
  organization_id?: string;
}

/** OAuth 2.0 token request (form-encoded). */
export interface ITokenRequest {
  grant_type: string;
  client_id?: string;
  client_secret?: string;
  scope?: string;
}

/** Successful OAuth 2.0 token response. */
export interface ITokenResponse {
  access_token: string;
  token_type: 'Bearer';
  expires_in: number;
  scope: string;
  /**
   * OIDC ID token — included when the `openid` scope is requested.
   * Signed RS256 or ES256 JWT containing agent identity claims.
   */
  id_token?: string;
}

/** OAuth 2.0 error response (RFC 6749 §5.2). */
export interface IOAuth2ErrorResponse {
  error: string;
  error_description: string;
}

/** Token introspection request (RFC 7662). */
export interface IIntrospectRequest {
  token: string;
  token_type_hint?: string;
}

/** Token introspection response (RFC 7662). */
export interface IIntrospectResponse {
  active: boolean;
  sub?: string;
  client_id?: string;
  scope?: string;
  token_type?: string;
  iat?: number;
  exp?: number;
}

/** Token revocation request (RFC 7009). */
export interface IRevokeRequest {
  token: string;
  token_type_hint?: string;
}

// ============================================================================
// Audit Log
// ============================================================================

/** An immutable audit event record. */
export interface IAuditEvent {
  eventId: string;
  agentId: string;
  action: AuditAction;
  outcome: AuditOutcome;
  ipAddress: string;
  userAgent: string;
  metadata: Record<string, unknown>;
  timestamp: Date;
}

/** Input for creating a new audit event. */
export interface ICreateAuditEventInput {
  agentId: string;
  /** Organization the event belongs to. Used for hash chain computation (SOC 2 CC7.2). */
  organizationId?: string;
  action: AuditAction;
  outcome: AuditOutcome;
  ipAddress: string;
  userAgent: string;
  metadata: Record<string, unknown>;
}

/** Paginated list of audit events. */
export interface IPaginatedAuditEventsResponse {
  data: IAuditEvent[];
  total: number;
  page: number;
  limit: number;
}

/** Query filters for the audit log. */
export interface IAuditListFilters {
  agentId?: string;
  action?: AuditAction;
  outcome?: AuditOutcome;
  fromDate?: string;
  toDate?: string;
  page: number;
  limit: number;
}

// ============================================================================
// API Error Response
// ============================================================================

/** Standard error response envelope used across all SentryAgent.ai APIs. */
export interface IErrorResponse {
  code: string;
  message: string;
  details?: Record<string, unknown>;
}

// ============================================================================
// Express type augmentation
// ============================================================================

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Express {
    interface Request {
      /** Decoded JWT payload attached by the auth middleware. */
      user?: ITokenPayload;
    }
  }
}
