use crate::Result;
use anyhow::anyhow;
use directories::ProjectDirs;
use std::path::PathBuf;

#[derive(Debug, Clone, Default)]
pub struct PathOverrides {
    pub config_dir: Option<PathBuf>,
    pub data_dir: Option<PathBuf>,
}

#[derive(Debug, Clone)]
pub struct AppPaths {
    pub config_dir: PathBuf,
    pub data_dir: PathBuf,
}

impl AppPaths {
    pub fn new(overrides: &PathOverrides) -> Result<Self> {
        if let (Some(config_dir), Some(data_dir)) = (&overrides.config_dir, &overrides.data_dir) {
            return Ok(Self {
                config_dir: config_dir.clone(),
                data_dir: data_dir.clone(),
            });
        }

        let project_dirs = ProjectDirs::from("de", "UniTrier", "studip-sync")
            .ok_or_else(|| anyhow!("Failed to determine XDG directories"))?;

        let config_dir = overrides
            .config_dir
            .clone()
            .unwrap_or_else(|| project_dirs.config_dir().to_path_buf());
        let data_dir = overrides
            .data_dir
            .clone()
            .unwrap_or_else(|| project_dirs.data_dir().to_path_buf());

        Ok(Self {
            config_dir,
            data_dir,
        })
    }

    pub fn ensure_dirs(&self) -> Result<()> {
        std::fs::create_dir_all(&self.config_dir)?;
        std::fs::create_dir_all(&self.data_dir)?;
        Ok(())
    }

    pub fn config_file(&self) -> PathBuf {
        self.config_dir.join("config.toml")
    }

    pub fn state_file(&self) -> PathBuf {
        self.data_dir.join("state.toml")
    }
}
