use std::collections::HashMap;

use serde_json::Value;
use zeroclaw::agent::TurnEvent;

use crate::pipe::AgentMessage;

pub fn log_entry_for_turn_event(
    event: &TurnEvent,
    skill_versions: &HashMap<String, String>,
) -> Option<AgentMessage> {
    match event {
        TurnEvent::ToolCall { name, args } => Some(AgentMessage::LogEntry {
            level: "info".to_string(),
            message: format_tool_call(name, args, skill_versions),
        }),
        TurnEvent::ToolResult { output, .. } if is_tool_error(output) => {
            Some(AgentMessage::LogEntry {
                level: "error".to_string(),
                message: output.trim_start_matches("Error: ").to_string(),
            })
        }
        _ => None,
    }
}

fn format_tool_call(name: &str, args: &Value, skill_versions: &HashMap<String, String>) -> String {
    if name == "read_skill" {
        let skill_name = args
            .get("name")
            .and_then(Value::as_str)
            .unwrap_or("<missing-skill>");
        if let Some(version) = skill_versions.get(skill_name) {
            return format!("read_skill {skill_name}@{version}");
        }
        return format!("read_skill {skill_name}");
    }

    if !is_browser_tool_call(name) {
        return format!("call {name}");
    }

    let action = args
        .get("action")
        .and_then(Value::as_str)
        .unwrap_or("unknown");

    match action {
        "navigate" => {
            let url = args
                .get("url")
                .and_then(Value::as_str)
                .unwrap_or("<missing-url>");
            format!("navigate {url}")
        }
        "type" => {
            let text = args.get("text").and_then(Value::as_str).unwrap_or("");
            let selector = args
                .get("selector")
                .and_then(Value::as_str)
                .unwrap_or("<missing-selector>");
            format!("type {text} into {selector}")
        }
        "click" => {
            let selector = args
                .get("selector")
                .and_then(Value::as_str)
                .unwrap_or("<missing-selector>");
            format!("click {selector}")
        }
        "getText" => {
            let selector = args
                .get("selector")
                .and_then(Value::as_str)
                .unwrap_or("<missing-selector>");
            format!("getText {selector}")
        }
        other => format!("{name} {other}"),
    }
}

fn is_browser_tool_call(name: &str) -> bool {
    name == "browser_action" || name == "superrpa_browser"
}

fn is_tool_error(output: &str) -> bool {
    output.starts_with("Error:")
}
