use std::io::{self, Write};

use agent_contracts::InteractionHandle;
use agent_types::interaction::{InteractionRequest, InteractionResponse};
use async_trait::async_trait;

pub struct CliInteractionHandle;

#[async_trait]
impl InteractionHandle for CliInteractionHandle {
    async fn ask(&self, request: &InteractionRequest) -> InteractionResponse {
        match request {
            InteractionRequest::Confirm { prompt, .. } => {
                let input = prompt_input(&format!(
                    "[tool-cli][interaction.confirm] {} [y/N]: ",
                    prompt
                ));
                let allowed = matches!(input.trim().to_ascii_lowercase().as_str(), "y" | "yes");
                InteractionResponse::Confirmed { allowed }
            }
            InteractionRequest::TextInput { prompt, .. } => {
                let input = prompt_input(&format!("[tool-cli][interaction.text] {}: ", prompt));
                InteractionResponse::Text {
                    value: if input.is_empty() { None } else { Some(input) },
                }
            }
            InteractionRequest::Choice {
                prompt, options, ..
            } => {
                eprintln!("[tool-cli][interaction.choice] {}", prompt);
                for option in options {
                    eprintln!("  - {}", option);
                }
                let input = prompt_input("choice: ");
                InteractionResponse::Choice {
                    value: if input.is_empty() { None } else { Some(input) },
                }
            }
        }
    }
}

fn prompt_input(prompt: &str) -> String {
    print!("{}", prompt);
    let _ = io::stdout().flush();

    let mut input = String::new();
    match io::stdin().read_line(&mut input) {
        Ok(_) => input.trim().to_string(),
        Err(error) => {
            eprintln!(
                "[tool-cli][interaction.error] failed to read stdin: {}",
                error
            );
            String::new()
        }
    }
}