use axum::http::{HeaderMap, HeaderValue};
use axum::response::IntoResponse;
use axum::Json;
use serde::Serialize;
use std::sync::LazyLock;
use std::time::{SystemTime, UNIX_EPOCH};

const HEADER_MNOTE_WEB_OWNER: &str = "x-mnote-web-owner";

static DEV_HOT_BOOT_ID: LazyLock<String> = LazyLock::new(|| {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map(|duration| duration.as_millis())
        .unwrap_or_default();
    format!("{}-{now}", std::process::id())
});

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DevHotReloadPayload {
    ok: bool,
    enabled: bool,
    boot_id: &'static str,
}

pub fn dev_hot_reload_enabled() -> bool {
    matches!(
        std::env::var("MNOTE_WEB_DEV_HOT_RELOAD")
            .unwrap_or_default()
            .trim()
            .to_ascii_lowercase()
            .as_str(),
        "1" | "true" | "yes" | "on"
    )
}

pub fn dev_hot_cache_buster() -> Option<&'static str> {
    dev_hot_reload_enabled().then_some(DEV_HOT_BOOT_ID.as_str())
}

pub async fn hot_reload() -> impl IntoResponse {
    let mut headers = HeaderMap::new();
    headers.insert(
        HEADER_MNOTE_WEB_OWNER,
        HeaderValue::from_static("mnote-web"),
    );
    (
        headers,
        Json(DevHotReloadPayload {
            ok: true,
            enabled: dev_hot_reload_enabled(),
            boot_id: DEV_HOT_BOOT_ID.as_str(),
        }),
    )
}
