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

/// Result of a successful scrape.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct Document {
    #[serde(default)]
    pub url: Option<String>,
    #[serde(default)]
    pub status_code: Option<i64>,
    #[serde(default)]
    pub html: Option<String>,
    #[serde(default)]
    pub markdown: Option<String>,
    #[serde(default)]
    pub text: Option<String>,
    #[serde(default)]
    pub title: Option<String>,
    #[serde(default)]
    pub metadata: Option<HashMap<String, serde_json::Value>>,
    #[serde(default)]
    pub extraction: Option<serde_json::Value>,
    #[serde(default)]
    pub screenshot: Option<String>,
}

/// Result of a /map call: discovered links for a domain.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct MapResult {
    #[serde(default)]
    pub url: Option<String>,
    #[serde(default)]
    pub links: Vec<String>,
    #[serde(default)]
    pub total: Option<i64>,
}

/// Result of a /crawl call: a batch of scraped pages.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct CrawlResult {
    #[serde(default)]
    pub url: Option<String>,
    #[serde(default)]
    pub pages: Vec<Document>,
    #[serde(default)]
    pub total: Option<i64>,
}

/// Result of a synchronous /search call.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct SearchResult {
    #[serde(default)]
    pub query: Option<String>,
    #[serde(default)]
    pub results: Vec<SearchHit>,
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct SearchHit {
    #[serde(default)]
    pub title: Option<String>,
    #[serde(default)]
    pub url: Option<String>,
    #[serde(default)]
    pub snippet: Option<String>,
}

/// Result of an /agentic-search call.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct AgenticSearchResult {
    #[serde(default)]
    pub answer: Option<String>,
    #[serde(default)]
    pub sources: Vec<AgenticSource>,
    #[serde(default)]
    pub data: Option<serde_json::Value>,
}

#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct AgenticSource {
    #[serde(default)]
    pub url: Option<String>,
    #[serde(default)]
    pub title: Option<String>,
}

/// Result of a Wire (Holocron) action execution.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct WireResult {
    #[serde(default)]
    pub action_id: Option<String>,
    #[serde(default)]
    pub output: Option<serde_json::Value>,
    #[serde(default)]
    pub error: Option<String>,
}

/// A saved browser session.
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct BrowserSession {
    #[serde(default)]
    pub id: Option<String>,
    #[serde(default)]
    pub name: Option<String>,
    #[serde(default)]
    pub description: Option<String>,
    #[serde(default)]
    pub created_at: Option<String>,
    #[serde(default)]
    pub updated_at: Option<String>,
    #[serde(default)]
    pub tags: Vec<String>,
}
