use std::sync::Arc;

use compliance_core::models::Finding;
use compliance_core::traits::issue_tracker::ReviewComment;

use crate::error::AgentError;
use crate::llm::LlmClient;

const PR_REVIEW_SYSTEM_PROMPT: &str = r#"You are a security-focused code reviewer. Given a list of security findings in a PR diff, generate concise review comments. Each comment should:
1. Briefly explain the issue
2. Suggest a specific fix
3. Reference the relevant security standard (CWE, OWASP) if applicable

Be constructive and professional. Return JSON array:
[{"path": "file.rs", "line": 42, "body": "..."}]"#;

pub async fn generate_pr_review(
    llm: &Arc<LlmClient>,
    findings: &[Finding],
) -> Result<(String, Vec<ReviewComment>), AgentError> {
    if findings.is_empty() {
        return Ok((
            "No security issues found in this PR.".to_string(),
            Vec::new(),
        ));
    }

    let findings_text: Vec<String> = findings
        .iter()
        .map(|f| {
            format!(
                "- [{severity}] {title} in {file}:{line}\n  Code: {code}\n  Rule: {rule}",
                severity = f.severity,
                title = f.title,
                file = f.file_path.as_deref().unwrap_or("unknown"),
                line = f
                    .line_number
                    .map(|n| n.to_string())
                    .unwrap_or_else(|| "?".to_string()),
                code = f.code_snippet.as_deref().unwrap_or("N/A"),
                rule = f.rule_id.as_deref().unwrap_or("N/A"),
            )
        })
        .collect();

    let user_prompt = format!(
        "Generate review comments for these {} findings:\n{}",
        findings.len(),
        findings_text.join("\n"),
    );

    let response = llm
        .chat(PR_REVIEW_SYSTEM_PROMPT, &user_prompt, Some(0.3))
        .await?;

    // Parse comments from LLM response
    let comments: Vec<ReviewComment> = serde_json::from_str::<Vec<PrComment>>(&response)
        .unwrap_or_default()
        .into_iter()
        .map(|c| ReviewComment {
            path: c.path,
            line: c.line,
            body: c.body,
        })
        .collect();

    let summary = format!(
        "## Security Review\n\nFound **{}** potential security issue(s) in this PR.\n\n{}",
        findings.len(),
        findings
            .iter()
            .map(|f| format!(
                "- **[{}]** {} in `{}`",
                f.severity,
                f.title,
                f.file_path.as_deref().unwrap_or("unknown")
            ))
            .collect::<Vec<_>>()
            .join("\n"),
    );

    Ok((summary, comments))
}

#[derive(serde::Deserialize)]
struct PrComment {
    path: String,
    line: u32,
    body: String,
}
