use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SavedRequest {
    pub name: String,
    pub method: String,
    pub path: String,
    pub headers: HashMap<String, String>,
    pub body: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Collection {
    pub name: String,
    pub requests: Vec<SavedRequest>,
}

impl Collection {
    pub fn load(name: &str) -> anyhow::Result<Self> {
        let path = format!(".rok-studio/collections/{name}.json");
        let content = std::fs::read_to_string(path)?;
        Ok(serde_json::from_str(&content)?)
    }

    pub fn save(&self) -> anyhow::Result<()> {
        let path = format!(".rok-studio/collections/{}.json", self.name);
        let json = serde_json::to_string_pretty(self)?;
        std::fs::write(path, json)?;
        Ok(())
    }

    pub fn add_request(&mut self, req: SavedRequest) {
        // Replace if same name exists
        if let Some(existing) = self.requests.iter_mut().find(|r| r.name == req.name) {
            *existing = req;
        } else {
            self.requests.push(req);
        }
    }
}

pub fn list_collections() -> Vec<String> {
    let dir = std::path::Path::new(".rok-studio/collections");
    if !dir.exists() {
        return Vec::new();
    }
    let Ok(entries) = std::fs::read_dir(dir) else {
        return Vec::new();
    };
    entries
        .filter_map(|e| e.ok())
        .filter_map(|e| {
            let p = e.path();
            if p.extension().and_then(|x| x.to_str()) == Some("json") {
                p.file_stem()
                    .and_then(|s| s.to_str())
                    .map(|s| s.to_string())
            } else {
                None
            }
        })
        .collect()
}
