//! Golden structs for Anthropic Messages API spec compliance.
//!
//! Derived from: https://docs.anthropic.com/en/api/messages
//! Streaming: https://docs.anthropic.com/en/api/messages-streaming
//! Target: latest API version (2025)

use serde::Deserialize;

// ---------------------------------------------------------------------------
// Non-streaming response
// ---------------------------------------------------------------------------

/// The Messages response object.
/// Spec: https://docs.anthropic.com/en/api/messages
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessagesResponse {
    /// Unique message identifier (format: `msg_...`).
    pub id: String,
    /// Object type, always `"message"`.
    #[serde(rename = "type")]
    pub msg_type: String,
    /// Conversational role, always `"assistant"`.
    pub role: String,
    /// Array of content blocks generated by the model.
    pub content: Vec<SpecContentBlock>,
    /// The model that handled the request.
    pub model: String,
    /// Reason the model stopped: `"end_turn"`, `"max_tokens"`, `"stop_sequence"`, `"tool_use"`.
    pub stop_reason: Option<String>,
    /// Which custom stop sequence was matched (if any).
    pub stop_sequence: Option<String>,
    /// Billing and rate-limit usage.
    pub usage: SpecAnthropicUsage,
}

/// A content block in the response.
// Note: deny_unknown_fields not supported on internally-tagged enums (serde limitation).
#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
pub enum SpecContentBlock {
    /// Text content block.
    #[serde(rename = "text")]
    Text {
        text: String,
        #[serde(default)]
        citations: Option<serde_json::Value>,
    },
    /// Tool use content block.
    #[serde(rename = "tool_use")]
    ToolUse {
        id: String,
        name: String,
        input: serde_json::Value,
    },
}

/// Usage statistics.
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecAnthropicUsage {
    pub input_tokens: u64,
    pub output_tokens: u64,
    /// Always emitted (0 when caching not used). Non-optional per latest API spec.
    pub cache_creation_input_tokens: u64,
    pub cache_read_input_tokens: u64,
}

// ---------------------------------------------------------------------------
// Streaming events
// ---------------------------------------------------------------------------

// Streaming event wrapper — each SSE event has an event type and JSON data.
// We parse events individually, not as a single struct.

/// message_start event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessageStartEvent {
    #[serde(rename = "type")]
    pub event_type: String,
    pub message: SpecMessageStartPayload,
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessageStartPayload {
    pub id: String,
    #[serde(rename = "type")]
    pub msg_type: String,
    pub role: String,
    pub model: String,
    pub content: Vec<serde_json::Value>,
    pub stop_reason: Option<String>,
    pub stop_sequence: Option<String>,
    pub usage: SpecAnthropicUsage,
}

/// content_block_start event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecContentBlockStartEvent {
    #[serde(rename = "type")]
    pub event_type: String,
    pub index: u64,
    pub content_block: SpecContentBlockStart,
}

// Note: deny_unknown_fields not supported on internally-tagged enums (serde limitation).
#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
pub enum SpecContentBlockStart {
    #[serde(rename = "text")]
    Text { text: String },
    #[serde(rename = "tool_use")]
    ToolUse {
        id: String,
        name: String,
        input: serde_json::Value,
    },
}

/// content_block_delta event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecContentBlockDeltaEvent {
    #[serde(rename = "type")]
    pub event_type: String,
    pub index: u64,
    pub delta: SpecDelta,
}

// Note: deny_unknown_fields is not supported on internally-tagged enums
// (#[serde(tag = "type")]) due to a serde limitation. Variant fields are
// therefore not strictly validated — if Anthropic adds fields to text_delta
// or input_json_delta, they'll be silently ignored here. This is an accepted
// trade-off vs switching to manual deserialization.
#[derive(Debug, Deserialize)]
#[serde(tag = "type")]
pub enum SpecDelta {
    #[serde(rename = "text_delta")]
    TextDelta { text: String },
    #[serde(rename = "input_json_delta")]
    InputJsonDelta { partial_json: String },
}

/// content_block_stop event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecContentBlockStopEvent {
    #[serde(rename = "type")]
    pub event_type: String,
    pub index: u64,
}

/// message_delta event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessageDeltaEvent {
    #[serde(rename = "type")]
    pub event_type: String,
    pub delta: SpecMessageDeltaPayload,
    pub usage: SpecMessageDeltaUsage,
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessageDeltaPayload {
    pub stop_reason: Option<String>,
    pub stop_sequence: Option<String>,
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessageDeltaUsage {
    pub input_tokens: u64,
    pub output_tokens: u64,
    pub cache_creation_input_tokens: u64,
    pub cache_read_input_tokens: u64,
}

/// message_stop event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecMessageStopEvent {
    #[serde(rename = "type")]
    pub event_type: String,
}

/// ping event data
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecPingEvent {
    #[serde(rename = "type")]
    pub event_type: String,
}

// ---------------------------------------------------------------------------
// Error response
// ---------------------------------------------------------------------------

/// Anthropic error response envelope.
/// Spec: https://docs.anthropic.com/en/api/errors
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecAnthropicErrorResponse {
    #[serde(rename = "type")]
    pub resp_type: String,
    pub error: SpecAnthropicError,
}

#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SpecAnthropicError {
    #[serde(rename = "type")]
    pub error_type: String,
    pub message: String,
}
