use crate::ServerType;

// Known platform/loader mappings
pub enum PlatformLoader {
    Bukkit,    // Bukkit API
    Spigot,    // Spigot API (Bukkit compatible)
    Paper,     // Paper API (Spigot compatible)
    Forge,     // Forge API
    NeoForge,  // NeoForge API (Forge fork)
    Fabric,    // Fabric API
    Quilt,     // Quilt API (Fabric compatible)
    Velocity,  // Velocity proxy
    BungeeCord, // BungeeCord proxy
    Waterfall, // Waterfall proxy (BungeeCord fork)
    Sponge,    // Sponge API
    Unknown,   // Unknown platform
}

// Maps the ServerType to a PlatformLoader
pub fn server_type_to_platform_loader(server_type: &ServerType) -> PlatformLoader {
    match server_type {
        ServerType::Paper => PlatformLoader::Paper,
        ServerType::Spigot => PlatformLoader::Spigot,
        ServerType::Bukkit => PlatformLoader::Bukkit,
        ServerType::Forge => PlatformLoader::Forge,
        ServerType::Fabric => PlatformLoader::Fabric,
        ServerType::Velocity => PlatformLoader::Velocity,
        ServerType::BungeeCord => PlatformLoader::BungeeCord,
        ServerType::Waterfall => PlatformLoader::Waterfall,
        ServerType::Vanilla => PlatformLoader::Unknown, // No specific loader for vanilla
        ServerType::Unknown => PlatformLoader::Unknown,
    }
}

// Standard Modrinth loader strings
pub fn get_modrinth_loader_strings(platform: &PlatformLoader) -> Vec<String> {
    match platform {
        PlatformLoader::Bukkit => vec!["bukkit".to_string(), "spigot".to_string(), "paper".to_string()],
        PlatformLoader::Spigot => vec!["spigot".to_string(), "paper".to_string()],
        PlatformLoader::Paper => vec!["paper".to_string()],
        PlatformLoader::Forge => vec!["forge".to_string()],
        PlatformLoader::NeoForge => vec!["neoforge".to_string()],
        PlatformLoader::Fabric => vec!["fabric".to_string()],
        PlatformLoader::Quilt => vec!["quilt".to_string(), "fabric".to_string()],
        PlatformLoader::Velocity => vec!["velocity".to_string()],
        PlatformLoader::BungeeCord => vec!["bungeecord".to_string(), "waterfall".to_string()],
        PlatformLoader::Waterfall => vec!["waterfall".to_string()],
        PlatformLoader::Sponge => vec!["sponge".to_string()],
        PlatformLoader::Unknown => vec![], // No specific loader strings
    }
}

// Compatible Modrinth loader strings (what the server can load)
pub fn get_compatible_modrinth_loaders(server_type: &ServerType) -> Vec<String> {
    let platform = server_type_to_platform_loader(server_type);

    match server_type {
        ServerType::Paper => {
            // Paper can load Paper, Spigot, and Bukkit plugins
            vec!["paper".to_string(), "spigot".to_string(), "bukkit".to_string()]
        },
        ServerType::Spigot => {
            // Spigot can load Spigot and Bukkit plugins
            vec!["spigot".to_string(), "bukkit".to_string()]
        },
        ServerType::Bukkit => {
            // Bukkit can only load Bukkit plugins
            vec!["bukkit".to_string()]
        },
        ServerType::Forge => {
            // Forge can load Forge plugins (and maybe Sponge)
            vec!["forge".to_string()]
        },
        ServerType::Fabric => {
            // Fabric can load Fabric plugins
            vec!["fabric".to_string()]
        },
        ServerType::Velocity => {
            // Velocity proxy
            vec!["velocity".to_string()]
        },
        ServerType::BungeeCord => {
            // BungeeCord can load BungeeCord plugins
            vec!["bungeecord".to_string()]
        },
        ServerType::Waterfall => {
            // Waterfall can load Waterfall and BungeeCord plugins
            vec!["waterfall".to_string(), "bungeecord".to_string()]
        },
        _ => {
            // For unknown server types, return an empty list
            vec![]
        }
    }
}

// Check if a version's loaders are compatible with the server type
pub fn is_version_compatible_with_server(version_loaders: &Vec<String>, server_type: &ServerType) -> bool {
    // If no loaders specified, it's possibly a universal plugin, consider it compatible
    if version_loaders.is_empty() {
        return true;
    }

    let compatible_loaders = get_compatible_modrinth_loaders(server_type);

    // If we don't know compatible loaders for this server type, be conservative and return false
    if compatible_loaders.is_empty() {
        return false;
    }

    // Check if any loader in the version matches any compatible loader
    version_loaders.iter().any(|loader| {
        compatible_loaders.iter().any(|compatible|
            loader.to_lowercase() == compatible.to_lowercase()
        )
    })
}