/** JSON-safe metadata carried across channel adapter boundaries. */
export type ChannelMetadataValue =
  | string
  | number
  | boolean
  | null
  | readonly ChannelMetadataValue[]
  | { readonly [key: string]: ChannelMetadataValue };

export type ChannelSenderKind = 'user' | 'agent' | 'system';
export type ChannelContentKind = 'text' | 'markdown' | 'code' | 'image' | 'file';
export type ChannelAdapterStatus = 'connected' | 'degraded' | 'disconnected';
export type ChannelAuthorizationRole = 'viewer' | 'operator' | 'admin';
export type ChannelOperation = 'message.send' | 'approval.create' | 'session.stop';

export interface ChannelAttachmentDto {
  id: string;
  name: string;
  mimeType: string | null;
  url: string;
  sizeBytes?: number;
}

/** Canonical transport-neutral message shape for official channel adapters. */
export interface ChannelMessageDto {
  id: string;
  channelName: string;
  channelId: string;
  senderId: string;
  senderKind: ChannelSenderKind;
  content: string;
  contentKind: ChannelContentKind;
  timestamp: string;
  threadId?: string;
  replyToId?: string;
  attachments?: readonly ChannelAttachmentDto[];
  metadata: Readonly<Record<string, ChannelMetadataValue>>;
}

/** Where an adapter must deliver a response for one normalized conversation turn. */
/** Provisioned external identity after adapter allowlist/pairing checks pass. */
export interface ChannelAuthorizedPrincipalDto {
  channelUserId: string;
  role: ChannelAuthorizationRole;
  /** Needed when gateway policy must authorize a privileged Mosaic operation. */
  mosaicUserId?: string;
}

/** Configuration-owned binding. Credentials are intentionally absent. */
export interface ChannelBindingDto {
  bindingId: string;
  channelName: string;
  workspaceId: string;
  channelId: string;
  logicalAgentId: string;
  principals: Readonly<Record<string, ChannelAuthorizedPrincipalDto>>;
}

export interface ChannelResponseTargetDto {
  channelId: string;
  threadId?: string;
}

/**
 * Stable channel-to-session route. Runtime provider, harness, model, process,
 * and native runtime session identifiers are intentionally absent.
 */
export interface ChannelConversationRouteDto {
  bindingId: string;
  logicalAgentId: string;
  conversationId: string;
  channelName: string;
  authorizationChannelId: string;
  responseTarget: ChannelResponseTargetDto;
}

/** Authorized adapter-to-gateway ingress after native translation. */
export interface ChannelIngressDto {
  correlationId: string;
  nativeMessageId: string;
  operation: ChannelOperation;
  principal: ChannelAuthorizedPrincipalDto;
  message: ChannelMessageDto;
  route: ChannelConversationRouteDto;
}

/** Gateway-to-adapter egress; runtime/provider identity remains gateway-internal. */
export interface ChannelEgressDto {
  correlationId: string;
  message: ChannelMessageDto;
  route: ChannelConversationRouteDto;
}

export interface ChannelAdapterHealthDto {
  status: ChannelAdapterStatus;
  detail?: string;
}
