use serde::{Deserialize, Serialize};

use crate::error::Result;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AgentCard {
    pub name: String,
    pub description: String,
    pub url: String,
    pub version: String,
    pub capabilities: AgentCapabilities,
    pub skills: Vec<AgentSkill>,
    pub authentication: AgentAuthentication,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AgentCapabilities {
    pub streaming: bool,
    #[serde(rename = "pushNotifications")]
    pub push_notifications: bool,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AgentSkill {
    pub id: String,
    pub name: String,
    pub description: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub mcp_tools: Option<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AgentAuthentication {
    pub schemes: Vec<String>,
}

pub struct AgentCardBuilder {
    name: String,
    description: String,
    url: String,
    version: String,
    skills: Vec<AgentSkill>,
}

impl AgentCardBuilder {
    pub fn new(name: String, url: String, version: String) -> Self {
        Self {
            name: name.clone(),
            description: format!("VAPORA {} agent", name),
            url,
            version,
            skills: Vec::new(),
        }
    }

    pub fn description(mut self, desc: String) -> Self {
        self.description = desc;
        self
    }

    pub fn add_skill(mut self, skill: AgentSkill) -> Self {
        self.skills.push(skill);
        self
    }

    pub fn build(self) -> Result<AgentCard> {
        Ok(AgentCard {
            name: self.name,
            description: self.description,
            url: self.url,
            version: self.version,
            capabilities: AgentCapabilities {
                streaming: true,
                push_notifications: false,
            },
            skills: self.skills,
            authentication: AgentAuthentication {
                schemes: vec!["bearer".to_string()],
            },
        })
    }
}

pub fn generate_default_agent_card(base_url: String, version: String) -> Result<AgentCard> {
    AgentCardBuilder::new(
        "vapora-agents".to_string(),
        format!("{}/a2a", base_url),
        version,
    )
    .description("VAPORA agent orchestration platform with learning-based selection".to_string())
    .add_skill(AgentSkill {
        id: "developer".to_string(),
        name: "Developer Agents".to_string(),
        description: "Code implementation agents".to_string(),
        mcp_tools: None,
    })
    .add_skill(AgentSkill {
        id: "reviewer".to_string(),
        name: "Reviewer Agents".to_string(),
        description: "Code review agents".to_string(),
        mcp_tools: None,
    })
    .add_skill(AgentSkill {
        id: "architect".to_string(),
        name: "Architect Agents".to_string(),
        description: "Architecture design agents".to_string(),
        mcp_tools: None,
    })
    .build()
}
