use axum::{ extract::{Path, Query, State}, Json, }; use serde::Deserialize; use serde_json::{json, Value}; use crate::{ app::AppState, error::AppResult, services::{club as club_svc, draft as draft_svc, match_service, profile as profile_svc}, }; #[derive(Deserialize)] pub struct DraftQuery { pub difficulty: Option, } /// Legacy endpoint: returns a pre-built random draft squad (no session state). pub async fn get_draft_squad( State(state): State, Query(query): Query, ) -> AppResult> { let difficulty = query.difficulty.as_deref().unwrap_or("beginner"); let generated = match_service::generate_opponent(&state.card_db, difficulty); Ok(Json(json!({ "mode": "draft", "difficulty": difficulty, "squad_rating": generated["squad_rating"], "formation": generated["formation"], "cards": generated["cards"], }))) } /// Start a new stateful FUT-style draft session. /// /// Returns a session ID and the 5 candidates for the first position (GK). /// The caller picks one candidate, then calls `POST /draft/sessions/:id/pick` /// until all 11 slots are filled. pub async fn post_draft_start( State(state): State, Query(query): Query, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let difficulty = query.difficulty.as_deref().unwrap_or("professional"); let session = draft_svc::start_draft(&state.pool, &state.card_db, &profile.id, difficulty).await?; Ok(Json(session)) } /// Get the current state of a draft session. pub async fn get_draft_session( State(state): State, Path(session_id): Path, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let session = draft_svc::get_draft(&state.pool, &state.card_db, &profile.id, &session_id).await?; Ok(Json(session)) } #[derive(Deserialize)] pub struct PickRequest { pub card_id: String, } /// Pick one card from the current candidates list. /// /// Advances the session to the next position. /// When the last pick is made the session status changes to "completed" /// and rewards (coins + optional pack) are granted automatically. pub async fn post_draft_pick( State(state): State, Path(session_id): Path, Json(req): Json, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let club = club_svc::get_club_by_profile(&state.pool, &profile.id).await?; let session = draft_svc::pick_card( &state.pool, &state.card_db, &club.id, &profile.id, &session_id, &req.card_id, ) .await?; Ok(Json(session)) } /// Abandon an active draft session. No rewards are granted. pub async fn post_draft_abandon( State(state): State, Path(session_id): Path, ) -> AppResult> { let profile = profile_svc::get_active_profile(&state.pool).await?; let result = draft_svc::abandon_draft(&state.pool, &profile.id, &session_id).await?; Ok(Json(result)) }