use std::{collections::HashMap, os::unix::process};

use axum::{
    Router,
    extract::{Path, Query},
    response::Result,
    routing::get,
};
use log::info;

use crate::{
    configuration::CONFIGURATION,
    parse::parse,
    server::{download_content, util::process_recipe},
    types::ServerError,
};

pub fn create_router() -> Result<Router, Box<dyn std::error::Error>> {
    let router = Router::new()
        .route("/", get(root))
        .route("/resource/{name}", get(get_resource).post(add_resource));
    Ok(router)
}

async fn root() -> &'static str {
    "NoManSky Server!"
}

async fn get_resource(
    Path(name): Path<String>,
    Query(query): Query<HashMap<String, String>>,
) -> Result<String> {
    let result = format!("Resource name: {:?}, Query: {:?}", name, query);
    println!("get_resource: {}", result);
    Ok(result)
}

async fn add_resource(
    Path(name): Path<String>,
    Query(_query): Query<HashMap<String, String>>,
) -> Result<String, ServerError> {
    let url;
    let config = CONFIGURATION.get().unwrap();

    if name.starts_with("http") {
        // If the name starts with "http", treat it as a URL
        url = name.clone();
    } else {
        // Otherwise, construct a URL from the name
        url = format!(
            "{}{}{}",
            config.main.base_url,
            if config.main.base_url.ends_with("/") {
                ""
            } else {
                "/"
            },
            name
        );
    }

    info!("Try to download resource {}", url);

    let response = download_content(&url).await?;

    let recipes = parse(&response);

    for recipe in recipes {
        process_recipe(&recipe).await?;
    }

    Ok(format!("Resource {} added.", name))
}
