pub mod planner;
pub mod runtime;

use std::path::PathBuf;

use crate::config::DeepSeekSettings;
use crate::pipe::{AgentMessage, BrowserMessage, BrowserPipeTool, PipeError, Transport};

pub fn execute_task<T: Transport>(
    transport: &T,
    browser_tool: &BrowserPipeTool<T>,
    instruction: &str,
) -> Result<String, PipeError> {
    let plan = planner::plan_instruction(instruction)
        .map_err(|err| PipeError::Protocol(err.to_string()))?;

    for step in &plan.steps {
        transport.send(&AgentMessage::LogEntry {
            level: "info".to_string(),
            message: step.log_message.clone(),
        })?;

        let result = browser_tool.invoke(
            step.action.clone(),
            step.params.clone(),
            &step.expected_domain,
        )?;
        if !result.success {
            return Err(PipeError::Protocol(format!(
                "browser action failed: {}",
                result.data
            )));
        }
    }

    Ok(plan.summary)
}

pub fn handle_browser_message<T: Transport + 'static>(
    transport: &T,
    browser_tool: &BrowserPipeTool<T>,
    message: BrowserMessage,
) -> Result<(), PipeError> {
    match message {
        BrowserMessage::SubmitTask { instruction } => {
            let completion = match DeepSeekSettings::from_env() {
                Ok(_) => match crate::compat::runtime::execute_task(
                    transport,
                    browser_tool.clone(),
                    &instruction,
                    &std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
                ) {
                    Ok(summary) => AgentMessage::TaskComplete {
                        success: true,
                        summary,
                    },
                    Err(err) => AgentMessage::TaskComplete {
                        success: false,
                        summary: err.to_string(),
                    },
                },
                Err(_) => match execute_task(transport, browser_tool, &instruction) {
                    Ok(summary) => AgentMessage::TaskComplete {
                        success: true,
                        summary,
                    },
                    Err(err) => AgentMessage::TaskComplete {
                        success: false,
                        summary: err.to_string(),
                    },
                },
            };
            transport.send(&completion)
        }
        BrowserMessage::Init { .. } => {
            eprintln!("ignoring duplicate init after handshake");
            Ok(())
        }
        BrowserMessage::Response { seq, .. } => {
            eprintln!("ignoring unsolicited response: seq={seq}");
            Ok(())
        }
    }
}
