use std::path::{Path, PathBuf};

use walkdir::WalkDir;

pub const IMAGE_EXTENSIONS: &[&str] = &[
    "jpg", "jpeg", "png", "webp", "avif", "gif", "tiff", "tif", "bmp",
];

pub fn is_image_extension(ext: &str) -> bool {
    IMAGE_EXTENSIONS.contains(&ext.to_lowercase().as_str())
}

pub fn discover_images(path: &Path, recursive: bool) -> Vec<PathBuf> {
    if path.is_file() {
        if let Some(ext) = path.extension().and_then(|e| e.to_str())
            && is_image_extension(ext)
        {
            return vec![path.to_path_buf()];
        }
        return Vec::new();
    }

    if !path.is_dir() {
        return Vec::new();
    }

    let max_depth = if recursive { usize::MAX } else { 1 };

    WalkDir::new(path)
        .max_depth(max_depth)
        .into_iter()
        .filter_map(|entry| entry.ok())
        .filter(|entry| entry.file_type().is_file())
        .filter(|entry| {
            entry
                .path()
                .extension()
                .and_then(|ext| ext.to_str())
                .is_some_and(is_image_extension)
        })
        .map(|entry| entry.into_path())
        .collect()
}

pub fn has_subdirectories(path: &Path) -> bool {
    if !path.is_dir() {
        return false;
    }
    std::fs::read_dir(path)
        .map(|entries| {
            entries
                .filter_map(|e| e.ok())
                .any(|e| e.file_type().is_ok_and(|ft| ft.is_dir()))
        })
        .unwrap_or(false)
}
