use super::models::{GameCandidate, GameSource};
use std::path::PathBuf;

pub mod epic;
pub mod gog;
pub mod local;
pub mod steam;

#[derive(Debug, Clone)]
pub struct ScanContext {
    pub local_folders: Vec<PathBuf>,
}

pub trait ScannerProvider: Send + Sync {
    fn source(&self) -> GameSource;
    fn scan(&self, context: &ScanContext) -> Result<Vec<GameCandidate>, String>;
}

#[cfg(any(target_os = "linux", target_os = "macos"))]
pub fn home_dir() -> Option<PathBuf> {
    std::env::var_os("HOME")
        .map(PathBuf::from)
        .or_else(|| std::env::var_os("USERPROFILE").map(PathBuf::from))
}

pub fn is_probably_game_executable(path: &std::path::Path) -> bool {
    let file_name = path
        .file_name()
        .and_then(|name| name.to_str())
        .unwrap_or_default()
        .to_lowercase();

    if file_name.is_empty() {
        return false;
    }

    let ignored_fragments = [
        "unins",
        "uninstall",
        "setup",
        "install",
        "redist",
        "vcredist",
        "crash",
        "reporter",
        "benchmark",
        "launcherhelper",
        "unitycrashhandler",
    ];

    !ignored_fragments
        .iter()
        .any(|fragment| file_name.contains(fragment))
}

pub fn title_from_path(path: &std::path::Path) -> String {
    path.file_stem()
        .or_else(|| path.file_name())
        .and_then(|name| name.to_str())
        .map(|value| {
            value
                .replace(['_', '-', '.'], " ")
                .split_whitespace()
                .collect::<Vec<_>>()
                .join(" ")
        })
        .filter(|value| !value.is_empty())
        .unwrap_or_else(|| "Unknown Game".to_string())
}
