use mlua::prelude::*;
use std::time::Duration;

const REQUEST_TIMEOUT: Duration = Duration::from_secs(30);

fn agent() -> ureq::Agent {
    ureq::AgentBuilder::new().timeout(REQUEST_TIMEOUT).build()
}

pub fn create(lua: &Lua) -> LuaResult<LuaTable> {
    let t = lua.create_table()?;

    t.set(
        "get",
        lua.create_function(|lua, url: String| {
            let resp = agent()
                .get(&url)
                .call()
                .map_err(|e| LuaError::external(e.to_string()))?;

            let status = resp.status();
            let body = resp
                .into_string()
                .map_err(|e| LuaError::external(e.to_string()))?;

            let result = lua.create_table()?;
            result.set("status", status)?;
            result.set("body", body)?;
            Ok(result)
        })?,
    )?;

    t.set(
        "post",
        lua.create_function(
            |lua, (url, body, content_type): (String, String, Option<String>)| {
                let ct = content_type.as_deref().unwrap_or("application/json");
                let resp = agent()
                    .post(&url)
                    .set("Content-Type", ct)
                    .send_string(&body)
                    .map_err(|e| LuaError::external(e.to_string()))?;

                let status = resp.status();
                let resp_body = resp
                    .into_string()
                    .map_err(|e| LuaError::external(e.to_string()))?;

                let result = lua.create_table()?;
                result.set("status", status)?;
                result.set("body", resp_body)?;
                Ok(result)
            },
        )?,
    )?;

    Ok(t)
}
