use clap::{Parser, Subcommand};
use indicatif::{ProgressBar, ProgressStyle};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::{Path, PathBuf};
use std::time::Duration;

#[derive(Parser)]
#[command(name = "kpn")]
#[command(about = "Kipinä Agent Local CLI", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Alustaa uuden Kipinä-agenttikansion nykyiseen projektiin
    Init {
        #[arg(short, long, default_value = "kipina-tasks")]
        dir: String,
    },
    /// Ajaa `.md` tiedostossa kuvatun tehtävän Kipinä-verkoston kautta
    Run {
        /// Polku `.md` työtiedostoon
        file: String,
    },
}

#[derive(Debug, Deserialize, Serialize)]
struct Frontmatter {
    agent: Option<String>,
    status: Option<String>,
    context: Option<Vec<String>>,
}

#[derive(Serialize)]
struct CompletionRequest {
    model: String,
    prompt: String,
    task_id: String,
}

#[derive(Deserialize)]
struct CompletionResponse {
    response: String,
    model: String,
    tokens_generated: u64,
}

#[tokio::main]
async fn main() {
    let cli = Cli::parse();

    match &cli.command {
        Commands::Init { dir } => {
            let path = Path::new(dir);
            if !path.exists() {
                fs::create_dir_all(path).unwrap();
                let example = format!("---\nstatus: open\nagent: qwen-coder-3b\ncontext: []\n---\n\n# Tehtävä\nKirjoita tähän mitä haluat verkon koodaavan.");
                fs::write(path.join("01-esimerkki.md"), example).unwrap();
                println!("✅ Alustettu lokaali agenttikansio: {}", dir);
            } else {
                println!("⚠️ Kansio {} on jo olemassa.", dir);
            }
        }
        Commands::Run { file } => {
            if let Err(e) = run_workflow(file).await {
                eprintln!("❌ Virhe: {}", e);
            }
        }
    }
}

async fn run_workflow(filepath: &str) -> Result<(), Box<dyn std::error::Error>> {
    let content = fs::read_to_string(filepath)?;
    
    // Yksinkertainen frontmatter-parseri
    let mut frontmatter_str = String::new();
    let mut body = String::new();
    let mut in_frontmatter = false;
    let mut fm_found = false;

    for line in content.lines() {
        if line.trim() == "---" {
            if !fm_found {
                in_frontmatter = true;
                fm_found = true;
                continue;
            } else if in_frontmatter {
                in_frontmatter = false;
                continue;
            }
        }
        
        if in_frontmatter {
            frontmatter_str.push_str(line);
            frontmatter_str.push('\n');
        } else {
            body.push_str(line);
            body.push('\n');
        }
    }

    let meta: Frontmatter = if fm_found {
        serde_yaml::from_str(&frontmatter_str).unwrap_or(Frontmatter { agent: None, status: None, context: None })
    } else {
        Frontmatter { agent: None, status: None, context: None }
    };

    let model = meta.agent.unwrap_or_else(|| "qwen-coder-05b".to_string());
    
    // Kerätään kontekstitiedostot
    let mut mega_prompt = body.trim().to_string();
    if let Some(ctx_files) = meta.context {
        mega_prompt.push_str("\n\n=== KONTEKSTI ===\n");
        for ctx in ctx_files {
            if let Ok(c) = fs::read_to_string(&ctx) {
                mega_prompt.push_str(&format!("\n--- Tiedosto: {} ---\n{}\n", ctx, c));
            } else {
                println!("⚠️ Varoitus: Kontekstitiedostoa {} ei löytynyt.", ctx);
            }
        }
    }

    println!("\n🚀 Lähetetään tehtävä Kipinäverkkoon (Malli: {})", model);
    
    let pb = ProgressBar::new_spinner();
    pb.enable_steady_tick(Duration::from_millis(100));
    pb.set_style(
        ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] {msg}")
            .unwrap()
            .tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]),
    );
    pb.set_message("Odotetaan verkon solmua ja laskentaa...");

    let task_id = uuid::Uuid::new_v4().to_string();

    let client = reqwest::Client::new();
    let req = CompletionRequest {
        model: model.clone(),
        prompt: mega_prompt.clone(),
        task_id: task_id.clone(),
    };

    let res = client.post("http://localhost:3000/api/v1/chat/completions")
        .json(&req)
        .send()
        .await?;

    if res.status().is_success() {
        let completion: CompletionResponse = res.json().await?;
        pb.finish_with_message(format!("Tulos saapui verkolta! ({} tokenia)", completion.tokens_generated));
        
        let new_content = format!("{}\n\n## Kipinä Agentin Ratkaisu\n{}\n", content, completion.response);
        let updated_content = new_content.replace("status: open", "status: done");
        fs::write(filepath, updated_content)?;
        println!("✅ Vastaus tallennettu tiedostoon: {}", filepath);
    } else {
        pb.finish_with_message("❌ Verkkopyyntö epäonnistui!");
        println!("Virhekoodi: {}", res.status());
    }

    Ok(())
}
