/**
 * Internal message types for the SANDCODE conversation system.
 *
 * These types represent the in-memory message store format. They wrap the
 * SDK/API types with additional internal fields (uuid, timestamp, origin, etc.).
 */

import type { UUID } from 'crypto'
import type { SDKAssistantMessageError, PermissionMode } from '../entrypoints/agentSdkTypes.js'
import type { Progress } from '../Tool.js'

// ============================================================================
// Re-export from SDK types that the original module also exported
// ============================================================================

// These are "phantom" re-exports — consumers expect them from types/message.
// The actual shapes come from the vendored SDK or our internal api types.
// We use `any` for SDK types here because they're defined in the SDK layer
// and will be replaced when we swap to native OpenAI types.

/** Anthropic SDK BetaMessage — the raw API response for an assistant turn. */
export type BetaMessage = {
  id: string
  container: unknown
  model: string
  role: 'assistant'
  stop_reason: string | null
  stop_sequence: string | null
  type: 'message'
  usage: BetaUsage
  content: BetaContentBlock[]
  context_management: unknown
}

export type BetaUsage = {
  input_tokens: number
  output_tokens: number
  cache_creation_input_tokens?: number
  cache_read_input_tokens?: number
  server_tool_use?: { web_search_requests: number; web_fetch_requests?: number }
  service_tier?: string | null
  cache_creation?: {
    ephemeral_1h_input_tokens: number
    ephemeral_5m_input_tokens: number
  }
  inference_geo?: string | null
  iterations?: number | null
  speed?: string | null
}

export type BetaContentBlock =
  | { type: 'text'; text: string; citations?: unknown[] }
  | { type: 'tool_use'; id: string; name: string; input: Record<string, unknown> }
  | { type: 'thinking'; thinking: string }
  | { type: 'redacted_thinking'; data: string }
  | { type: 'connector_text'; connector_text: string; source_tool_use_id?: string }

export type ContentBlockParam =
  | { type: 'text'; text: string }
  | { type: 'tool_use'; id: string; name: string; input: unknown }
  | {
      type: 'tool_result'
      tool_use_id: string
      content: string | ContentBlockParam[]
      is_error?: boolean
    }
  | { type: 'image'; source: { type: 'base64'; media_type: string; data: string } }
  | { type: 'thinking'; thinking: string }
  | { type: 'redacted_thinking'; data: string }

export type RawMessageStreamEvent =
  | { type: 'message_start'; message: BetaMessage }
  | { type: 'content_block_start'; index: number; content_block: BetaContentBlock }
  | { type: 'content_block_delta'; index: number; delta: unknown }
  | { type: 'content_block_stop'; index: number }
  | { type: 'message_delta'; delta: { stop_reason?: string }; usage?: { output_tokens: number } }
  | { type: 'message_stop' }

export type APIError = Error & {
  status?: number
  error?: unknown
  cause?: Error
}

// ============================================================================
// Message Origin
// ============================================================================

export type MessageOrigin =
  | { kind: 'human' }
  | { kind: 'channel'; server?: string }
  | { kind: 'task-notification' }
  | { kind: 'coordinator' }
  | { kind: string }

// ============================================================================
// System Message Levels
// ============================================================================

export type SystemMessageLevel = 'info' | 'warning' | 'error'

// ============================================================================
// Compact Direction
// ============================================================================

export type PartialCompactDirection = 'backward' | 'forward'

// ============================================================================
// Core Message Types
// ============================================================================

export interface AssistantMessage {
  type: 'assistant'
  uuid: UUID
  timestamp: string
  message: BetaMessage
  requestId?: string | undefined
  apiError?: { status: number; error: unknown }
  error?: SDKAssistantMessageError
  errorDetails?: string
  isApiErrorMessage?: boolean
  isVirtual?: true
  isMeta?: true
  advisorModel?: string
}

export interface UserMessage {
  type: 'user'
  uuid: UUID
  timestamp: string
  message: { role: 'user'; content: string | ContentBlockParam[] }
  isMeta?: true
  isVisibleInTranscriptOnly?: true
  isVirtual?: true
  isCompactSummary?: true
  summarizeMetadata?: {
    messagesSummarized: number
    userContext?: string
    direction?: PartialCompactDirection
  }
  toolUseResult?: unknown
  mcpMeta?: {
    _meta?: Record<string, unknown>
    structuredContent?: Record<string, unknown>
  }
  imagePasteIds?: number[]
  sourceToolAssistantUUID?: UUID
  permissionMode?: PermissionMode
  origin?: MessageOrigin
}

export interface ProgressMessage<P extends Progress = Progress> {
  type: 'progress'
  data: P
  toolUseID: string
  parentToolUseID: string
  uuid: UUID
  timestamp: string
}

export interface AttachmentMessage {
  type: 'attachment'
  attachment: import('../utils/attachments.js').Attachment
  uuid: UUID
  timestamp: string
}

// ============================================================================
// System Message Subtypes
// ============================================================================

interface SystemMessageBase {
  type: 'system'
  uuid: UUID
  timestamp: string
  isMeta: false
}

export interface SystemInformationalMessage extends SystemMessageBase {
  subtype: 'informational'
  content: string
  level: SystemMessageLevel
  toolUseID?: string
  preventContinuation?: boolean
}

export interface SystemPermissionRetryMessage extends SystemMessageBase {
  subtype: 'permission_retry'
  content: string
  commands: string[]
  level: 'info'
}

export interface SystemBridgeStatusMessage extends SystemMessageBase {
  subtype: 'bridge_status'
  content: string
  url: string
  upgradeNudge?: string
}

export interface SystemScheduledTaskFireMessage extends SystemMessageBase {
  subtype: 'scheduled_task_fire'
  content: string
}

export interface SystemStopHookSummaryMessage extends SystemMessageBase {
  subtype: 'stop_hook_summary'
  hookCount: number
  hookInfos: StopHookInfo[]
  hookErrors: string[]
  preventedContinuation: boolean
  stopReason: string | undefined
  hasOutput: boolean
  level: SystemMessageLevel
  toolUseID?: string
  hookLabel?: string
  totalDurationMs?: number
}

export interface SystemTurnDurationMessage extends SystemMessageBase {
  subtype: 'turn_duration'
  durationMs: number
  budgetTokens?: number
  budgetLimit?: number
  budgetNudges?: number
  messageCount?: number
}

export interface SystemAwaySummaryMessage extends SystemMessageBase {
  subtype: 'away_summary'
  content: string
}

export interface SystemMemorySavedMessage extends SystemMessageBase {
  subtype: 'memory_saved'
  writtenPaths: string[]
}

export interface SystemAgentsKilledMessage extends SystemMessageBase {
  subtype: 'agents_killed'
}

export interface SystemApiMetricsMessage extends SystemMessageBase {
  subtype: 'api_metrics'
  ttftMs: number
  otps: number
  isP50?: boolean
  hookDurationMs?: number
  turnDurationMs?: number
  toolDurationMs?: number
  classifierDurationMs?: number
  toolCount?: number
  hookCount?: number
  classifierCount?: number
  configWriteCount?: number
}

export interface SystemLocalCommandMessage extends SystemMessageBase {
  subtype: 'local_command'
  content: string
  level: 'info'
}

export interface CompactMetadata {
  trigger: 'manual' | 'auto'
  preTokens: number
  userContext?: string
  messagesSummarized?: number
  preservedSegment?: {
    headUuid: UUID
    anchorUuid: UUID
    tailUuid: UUID
  }
}

export interface SystemCompactBoundaryMessage extends SystemMessageBase {
  subtype: 'compact_boundary'
  content: string
  level: 'info'
  compactMetadata: CompactMetadata
  logicalParentUuid?: UUID
}

export interface SystemMicrocompactBoundaryMessage extends SystemMessageBase {
  subtype: 'microcompact_boundary'
  content: string
  level: 'info'
  microcompactMetadata: {
    trigger: 'auto'
    preTokens: number
    tokensSaved: number
    compactedToolIds: string[]
    clearedAttachmentUUIDs: string[]
  }
}

export interface SystemAPIErrorMessage extends SystemMessageBase {
  subtype: 'api_error'
  level: 'error'
  error: APIError
  cause?: Error
  retryInMs: number
  retryAttempt: number
  maxRetries: number
}

export type SystemMessage =
  | SystemInformationalMessage
  | SystemPermissionRetryMessage
  | SystemBridgeStatusMessage
  | SystemScheduledTaskFireMessage
  | SystemStopHookSummaryMessage
  | SystemTurnDurationMessage
  | SystemAwaySummaryMessage
  | SystemMemorySavedMessage
  | SystemAgentsKilledMessage
  | SystemApiMetricsMessage
  | SystemLocalCommandMessage
  | SystemCompactBoundaryMessage
  | SystemMicrocompactBoundaryMessage
  | SystemAPIErrorMessage

// ============================================================================
// Tombstone & ToolUseSummary
// ============================================================================

export interface TombstoneMessage {
  type: 'tombstone'
  message: Message
}

export interface ToolUseSummaryMessage {
  type: 'tool_use_summary'
  summary: string
  precedingToolUseIds: string[]
  uuid: UUID
  timestamp: string
}

// ============================================================================
// Message Union
// ============================================================================

export type Message =
  | AssistantMessage
  | UserMessage
  | ProgressMessage
  | AttachmentMessage
  | SystemMessage
  | TombstoneMessage
  | ToolUseSummaryMessage

// ============================================================================
// Normalized Messages (single content block per message)
// ============================================================================

export type NormalizedAssistantMessage = Omit<AssistantMessage, 'message'> & {
  message: Omit<BetaMessage, 'content'> & { content: [BetaContentBlock] }
}

export type NormalizedUserMessage = Omit<UserMessage, 'message'> & {
  message: { role: 'user'; content: [ContentBlockParam] }
}

export type NormalizedMessage =
  | NormalizedAssistantMessage
  | NormalizedUserMessage
  | ProgressMessage
  | AttachmentMessage
  | SystemMessage
  | TombstoneMessage
  | ToolUseSummaryMessage

// ============================================================================
// Stream & Request Events
// ============================================================================

export interface StreamEvent {
  type: 'stream_event'
  event: RawMessageStreamEvent
  ttftMs?: number
}

export interface RequestStartEvent {
  type: 'stream_request_start'
}

// ============================================================================
// Stop Hook Info
// ============================================================================

export interface StopHookInfo {
  command: string
  promptText: string
  durationMs?: number
}
