use crate::{ db::Pool, error::{AppError, AppResult}, models::squad::{SaveSquadRequest, Squad, SquadPlayer}, }; use uuid::Uuid; pub async fn get_squad(pool: &Pool, club_id: &str) -> AppResult<(Squad, Vec)> { let squad = sqlx::query_as::<_, Squad>( "SELECT id, club_id, name, formation, created_at, updated_at FROM squads WHERE club_id = ? ORDER BY created_at DESC LIMIT 1" ) .bind(club_id) .fetch_optional(pool) .await? .ok_or_else(|| AppError::NotFound("no squad found for this club".into()))?; let players = sqlx::query_as::<_, SquadPlayer>( "SELECT id, squad_id, owned_card_id, position_index, is_captain, is_on_bench FROM squad_players WHERE squad_id = ?" ) .bind(&squad.id) .fetch_all(pool) .await?; Ok((squad, players)) } pub async fn save_squad(pool: &Pool, club_id: &str, req: &SaveSquadRequest) -> AppResult { let now = chrono::Utc::now().to_rfc3339(); let existing = sqlx::query_scalar::<_, Option>( "SELECT id FROM squads WHERE club_id = ? ORDER BY created_at DESC LIMIT 1", ) .bind(club_id) .fetch_one(pool) .await?; let squad_id = if let Some(id) = existing { sqlx::query("UPDATE squads SET name = COALESCE(?, name), formation = COALESCE(?, formation), updated_at = ? WHERE id = ?") .bind(req.name.as_deref()) .bind(req.formation.as_deref()) .bind(&now) .bind(&id) .execute(pool) .await?; sqlx::query("DELETE FROM squad_players WHERE squad_id = ?") .bind(&id) .execute(pool) .await?; id } else { let squad = Squad::new( club_id, req.name.as_deref().unwrap_or("My Squad"), req.formation.as_deref().unwrap_or("4-4-2"), ); sqlx::query( "INSERT INTO squads (id, club_id, name, formation, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)" ) .bind(&squad.id) .bind(&squad.club_id) .bind(&squad.name) .bind(&squad.formation) .bind(&squad.created_at) .bind(&squad.updated_at) .execute(pool) .await?; squad.id }; for player in &req.players { let sp_id = Uuid::new_v4().to_string(); sqlx::query( "INSERT INTO squad_players (id, squad_id, owned_card_id, position_index, is_captain, is_on_bench) VALUES (?, ?, ?, ?, ?, ?)" ) .bind(&sp_id) .bind(&squad_id) .bind(&player.owned_card_id) .bind(player.position_index) .bind(player.is_captain) .bind(player.is_on_bench) .execute(pool) .await?; } let squad = sqlx::query_as::<_, Squad>( "SELECT id, club_id, name, formation, created_at, updated_at FROM squads WHERE id = ?", ) .bind(&squad_id) .fetch_one(pool) .await?; Ok(squad) }