use std::sync::Arc;

use axum::{
    extract::State,
    routing::{get, put},
    Json, Router,
};

use crate::db;
use crate::middleware::auth::AuthUser;
use crate::models::error::{ApiError, ApiResult};
use crate::models::public::{PublicSiteConfig, UpdatePublicSiteRequest};
use crate::AppState;

pub fn router() -> Router<Arc<AppState>> {
    Router::new()
        .route("/public-site", get(get_public_site_settings))
        .route("/public-site", put(update_public_site_settings))
}

/// GET /api/settings/public-site — Get public site configuration
async fn get_public_site_settings(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
) -> ApiResult<Json<PublicSiteConfig>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    let config = db::public::get_public_site_config(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(format!("Failed to fetch config: {}", e)))?;

    match config {
        Some(cfg) => Ok(Json(cfg)),
        None => {
            // Create default config if none exists
            let config_id = db::public::create_public_site_config(&state.db, license_id)
                .await
                .map_err(|e| ApiError::Internal(format!("Failed to create config: {}", e)))?;

            // Fetch the newly created config
            let new_config = db::public::get_public_site_config(&state.db, license_id)
                .await
                .map_err(|e| ApiError::Internal(format!("Failed to fetch new config: {}", e)))?
                .ok_or_else(|| ApiError::Internal("Config creation failed".to_string()))?;

            Ok(Json(new_config))
        }
    }
}

/// PUT /api/settings/public-site — Update public site configuration
async fn update_public_site_settings(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
    Json(req): Json<UpdatePublicSiteRequest>,
) -> ApiResult<Json<serde_json::Value>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    // Ensure config exists
    let config_exists = db::public::get_public_site_config(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(format!("Failed to check config: {}", e)))?;

    if config_exists.is_none() {
        db::public::create_public_site_config(&state.db, license_id)
            .await
            .map_err(|e| ApiError::Internal(format!("Failed to create config: {}", e)))?;
    }

    // Update fields
    db::public::update_public_site_config(
        &state.db,
        license_id,
        req.show_on_status_page,
        req.status_page_description,
        req.site_enabled,
    )
    .await
    .map_err(|e| ApiError::Internal(format!("Failed to update config: {}", e)))?;

    Ok(Json(serde_json::json!({
        "success": true,
        "message": "Public site settings updated"
    })))
}
