use axum::{
    extract::State,
    http::{header::CACHE_CONTROL, HeaderValue},
    response::{IntoResponse, Redirect},
    routing::get,
    Router,
};
use tower::ServiceBuilder;
use tower_http::{
    services::{ServeDir, ServeFile},
    set_header::SetResponseHeaderLayer,
};

use crate::{
    app_state::AppState, auth, channels_router, projects_router, settings::Settings, teams_router,
    v0_router,
};

pub fn new_router(state: AppState) -> Router<()> {
    let base_path = state.settings.base_path.clone();
    let ui_router = Router::new()
        .route("/", get(landing_page))
        .merge(channels_router::new_router())
        .merge(projects_router::new_router())
        .merge(teams_router::new_router());
    let app = Router::new()
        .route("/", get(landing_page))
        .merge(v0_router::new_router())
        .nest("/en", ui_router)
        .nest("/auth", auth::new_router())
        .layer(SetResponseHeaderLayer::if_not_present(
            CACHE_CONTROL,
            HeaderValue::from_static("no-cache"),
        ))
        .fallback_service(
            ServiceBuilder::new()
                .layer(SetResponseHeaderLayer::if_not_present(
                    CACHE_CONTROL,
                    HeaderValue::from_static("max-age=21600, stale-while-revalidate=86400"),
                ))
                .service(
                    ServeDir::new("static").not_found_service(
                        ServiceBuilder::new()
                            .layer(SetResponseHeaderLayer::if_not_present(
                                CACHE_CONTROL,
                                HeaderValue::from_static("no-cache"),
                            ))
                            .service(ServeFile::new("static/_404.html")),
                    ),
                ),
        )
        .with_state(state);
    if base_path.is_empty() {
        app
    } else {
        Router::new().nest(&base_path, app).fallback_service(
            ServeDir::new("static").not_found_service(ServeFile::new("static/_404.html")),
        )
    }
}

async fn landing_page(State(Settings { base_path, .. }): State<Settings>) -> impl IntoResponse {
    Redirect::to(&format!("{}/en/teams", base_path))
}
