//! Observability view types for session recording and replay

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// A single recorded step in a browser automation session
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StepRecord {
    /// Sequential step index (0-based)
    pub step_index: usize,
    /// ISO 8601 timestamp of when the step was recorded
    pub timestamp: String,
    /// Action type (e.g., "navigate", "click", "input")
    pub action_type: String,
    /// Action parameters
    pub params: HashMap<String, serde_json::Value>,
    /// Current page URL at the time of the action
    pub url: Option<String>,
    /// DOM snapshot (serialized DOM text) captured before the action
    pub dom_snapshot: Option<String>,
    /// Result of the action
    pub result: StepResult,
    /// Duration of the action in milliseconds
    pub duration_ms: u64,
}

/// Result of a recorded step
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StepResult {
    /// Whether the action succeeded
    pub success: bool,
    /// Extracted content or memory string from the action
    pub extracted_content: Option<String>,
    /// Error message if the action failed
    pub error: Option<String>,
}

impl StepResult {
    /// Create a success result
    pub fn success(extracted_content: Option<String>) -> Self {
        Self {
            success: true,
            extracted_content,
            error: None,
        }
    }

    /// Create a failure result
    pub fn failure(error: String) -> Self {
        Self {
            success: false,
            extracted_content: None,
            error: Some(error),
        }
    }
}

/// Complete session trace for export
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionTrace {
    /// Trace metadata
    pub metadata: TraceMetadata,
    /// Recorded steps
    pub steps: Vec<StepRecord>,
}

/// Metadata for a session trace
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TraceMetadata {
    /// Session start timestamp
    pub started_at: String,
    /// Session end timestamp
    pub ended_at: Option<String>,
    /// Total number of steps
    pub total_steps: usize,
    /// Number of successful steps
    pub success_count: usize,
    /// Number of failed steps
    pub failure_count: usize,
    /// Library version
    pub version: String,
}

/// Configuration for session recording
#[derive(Debug, Clone, Copy)]
pub struct RecorderConfig {
    /// Maximum number of steps to retain (oldest dropped when exceeded)
    pub max_steps: usize,
    /// Whether to capture DOM snapshots for each step
    pub capture_dom: bool,
    /// Maximum DOM snapshot size in characters (0 = unlimited)
    pub max_dom_chars: usize,
}

impl Default for RecorderConfig {
    fn default() -> Self {
        Self {
            max_steps: 1000,
            capture_dom: true,
            max_dom_chars: 50_000,
        }
    }
}

impl RecorderConfig {
    /// Create a minimal config (no DOM snapshots, small step limit)
    pub fn minimal() -> Self {
        Self {
            max_steps: 100,
            capture_dom: false,
            max_dom_chars: 0,
        }
    }

    /// Create a debug config (full DOM snapshots, large step limit)
    pub fn debug() -> Self {
        Self {
            max_steps: 10_000,
            capture_dom: true,
            max_dom_chars: 0,
        }
    }
}
