use crate::extractors::GameId; use axum::{ extract::{Path, State}, Json, }; use serde_json::{json, Value}; use crate::{ app::AppState, error::{AppError, AppResult}, models::sbc::{SaveSbcSquadRequest, SbcResult, SubmitSbcRequest}, services::{club as club_svc, profile as profile_svc, sbc as sbc_svc}, }; pub async fn get_sbcs(State(state): State) -> AppResult> { Ok(Json(json!({ "sbcs": state.sbc_defs }))) } pub async fn get_sbc( State(state): State, Path(sbc_id): Path, ) -> AppResult> { let sbc = state .sbc_defs .iter() .find(|s| s.id == sbc_id) .ok_or_else(|| AppError::NotFound(format!("SBC '{sbc_id}' not found")))?; Ok(Json(json!({ "sbc": sbc }))) } pub async fn get_sbc_status(State(state): State, game: GameId) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?; let completions = sbc_svc::completion_counts(&state.pool, &profile.id).await?; Ok(Json(json!({ "completions": completions }))) } pub async fn get_sbc_squad( State(state): State, game: GameId, Path(sbc_id): Path, ) -> AppResult> { if !state .sbc_defs .iter() .any(|definition| definition.id == sbc_id) { return Err(AppError::NotFound(format!("SBC '{sbc_id}' not found"))); } let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?; let squad = sbc_svc::load_sbc_squad(&state.pool, &profile.id, &sbc_id).await?; Ok(Json(json!({ "squad": squad }))) } pub async fn put_sbc_squad( State(state): State, game: GameId, Path(sbc_id): Path, Json(req): Json, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?; let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?; let squad = sbc_svc::save_sbc_squad( &state.pool, &state.sbc_defs, &profile.id, &club.id, &sbc_id, &req.owned_card_ids, ) .await?; Ok(Json(json!({ "squad": squad }))) } pub async fn post_sbc_submit( State(state): State, game: GameId, Json(req): Json, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool, game.as_str()).await?; let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?; let result = sbc_svc::submit_sbc( &state.pool, sbc_svc::SbcSubmissionContext { card_db: &state.card_db, sbc_defs: &state.sbc_defs, objective_defs: &state.obj_defs, achievement_defs: &state.achievement_defs, profile_id: &profile.id, club_id: &club.id, }, &req, ) .await?; Ok(Json(result)) }