use axum::{
    http::{header, HeaderMap},
    response::Redirect,
};
use loco_rs::prelude::*;
use serde::Deserialize;

pub const LANG_COOKIE: &str = "lang";

#[derive(Debug, Deserialize)]
pub struct LangForm {
    pub lang: String,
}

pub fn current_lang(jar: &axum_extra::extract::cookie::CookieJar) -> String {
    match jar
        .get(LANG_COOKIE)
        .map(|cookie| cookie.value().to_string())
    {
        Some(ref lang) if lang == "en" => "en".to_string(),
        _ => "sk".to_string(),
    }
}

#[debug_handler]
async fn set_lang(headers: HeaderMap, Form(form): Form<LangForm>) -> Result<Response> {
    let lang = if form.lang == "en" { "en" } else { "sk" };
    let cookie = format!("{LANG_COOKIE}={lang}; Path=/; Max-Age=31536000; SameSite=Lax");

    Ok((
        [(header::SET_COOKIE, cookie)],
        Redirect::to(&back_path(&headers)),
    )
        .into_response())
}

fn back_path(headers: &HeaderMap) -> String {
    let raw = headers
        .get(header::REFERER)
        .and_then(|value| value.to_str().ok())
        .unwrap_or("/");

    if raw.starts_with('/') {
        return raw.to_string();
    }

    if let Some(after_scheme) = raw.split_once("://").map(|(_, rest)| rest) {
        if let Some(path_start) = after_scheme.find('/') {
            let path = &after_scheme[path_start..];
            return if path.starts_with('/') {
                path.to_string()
            } else {
                "/".to_string()
            };
        }
    }

    "/".to_string()
}

pub fn routes() -> Routes {
    Routes::new().add("/lang", post(set_lang))
}
