use anyhow::Result;
use std::process::Command;

use crate::ai::prompt;
use crate::ai::types::AiBackend;
use crate::rules::matcher::Finding;

pub struct ClaudeCliBackend;

impl Default for ClaudeCliBackend {
    fn default() -> Self {
        Self
    }
}

impl ClaudeCliBackend {
    pub fn new() -> Self {
        Self
    }

    fn call_claude(&self, prompt_text: &str) -> Result<String> {
        let output = Command::new("claude").args(["-p", prompt_text]).output()?;

        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            anyhow::bail!("Claude CLI failed: {}", stderr);
        }

        let response = String::from_utf8_lossy(&output.stdout).to_string();
        Ok(response.trim().to_string())
    }
}

impl AiBackend for ClaudeCliBackend {
    fn explain(&self, finding: &Finding, code_context: &str) -> Result<String> {
        let prompt_text = prompt::explain_prompt(finding, code_context);
        self.call_claude(&prompt_text)
    }

    fn deep_review(&self, file_content: &str, language: &str) -> Result<String> {
        let prompt_text = prompt::review_prompt(file_content, language);
        self.call_claude(&prompt_text)
    }

    fn fix_file(
        &self,
        file_path: &str,
        language: &str,
        file_content: &str,
        findings: &[&Finding],
    ) -> Result<String> {
        let prompt_text = prompt::fix_file_prompt(file_path, language, file_content, findings);
        self.call_claude(&prompt_text)
    }
}
