use shared::Float;
use std::fs;
use std::io::{self, Error, ErrorKind};
use std::path::{Path, PathBuf};
use std::sync::OnceLock;

static SEARCH_DIRECTORY: OnceLock<PathBuf> = OnceLock::new();

pub fn set_search_directory(filename: &str) {
    let path = Path::new(filename);
    let dir = if path.is_dir() {
        path.to_path_buf()
    } else {
        path.parent().unwrap_or(Path::new("")).to_path_buf()
    };
    let _ = SEARCH_DIRECTORY.set(dir);
}

pub fn resolve_filename(filename: &str) -> String {
    let search_directory = SEARCH_DIRECTORY
        .get()
        .map(|p| p.as_path())
        .unwrap_or(Path::new(""));

    if search_directory.as_os_str().is_empty()
        || filename.is_empty()
        || Path::new(filename).is_absolute()
    {
        return filename.to_string();
    }

    let filepath = search_directory.join(filename);
    if filepath.exists() {
        filepath
            .canonicalize()
            .unwrap_or_else(|_| filepath.to_path_buf())
            .to_string_lossy()
            .to_string()
    } else {
        filename.to_string()
    }
}

pub fn read_float_file(filename: &str) -> io::Result<Vec<Float>> {
    let content = fs::read_to_string(filename)?;

    let mut values = Vec::new();

    for (line_num, line) in content.lines().enumerate() {
        // Strip comments
        let cleaned = line.split('#').next().unwrap_or("");

        for token in cleaned.split_whitespace() {
            match token.parse::<Float>() {
                Ok(val) => values.push(val),
                Err(e) => {
                    return Err(Error::new(
                        ErrorKind::InvalidData,
                        format!(
                            "Failed to parse float '{}' at line {}: {}",
                            token,
                            line_num + 1,
                            e
                        ),
                    ));
                }
            }
        }
    }

    Ok(values)
}
