use serde::{Deserialize, Serialize};
use std::fs;
use std::io::{BufRead, Write};
use std::path::PathBuf;

#[derive(Serialize, Deserialize)]
pub struct FundingSnapshot {
    pub timestamp: i64,
    pub symbol: String,
    pub funding_rate: f64,
}

pub fn history_path() -> PathBuf {
    dirs::data_local_dir()
        .unwrap_or_else(|| PathBuf::from("."))
        .join("bpx")
        .join("funding_history.jsonl")
}

pub fn append_snapshots(snapshots: &[FundingSnapshot]) -> anyhow::Result<()> {
    let path = history_path();
    if let Some(parent) = path.parent() {
        fs::create_dir_all(parent)?;
    }
    let mut file = fs::OpenOptions::new()
        .create(true)
        .append(true)
        .open(&path)?;
    for snap in snapshots {
        let line = serde_json::to_string(snap)?;
        writeln!(file, "{}", line)?;
    }
    Ok(())
}

pub fn load_recent(symbol: &str, count: usize) -> Vec<FundingSnapshot> {
    let path = history_path();
    let file = match fs::File::open(&path) {
        Ok(f) => f,
        Err(_) => return Vec::new(),
    };
    let reader = std::io::BufReader::new(file);
    let mut matching: Vec<FundingSnapshot> = reader
        .lines()
        .map_while(Result::ok)
        .filter_map(|line| serde_json::from_str::<FundingSnapshot>(&line).ok())
        .filter(|s| s.symbol == symbol)
        .collect();
    // Keep only the last `count` entries
    if matching.len() > count {
        matching.drain(..matching.len() - count);
    }
    matching
}
