// {{{ Imports
use crate::context::AppContext;
use crate::error::AppError;
use anyhow::anyhow;
use axum::{extract::State, http::StatusCode, Json};
use chrono::{TimeDelta, Utc};
use shimmeringmoon::arcaea::play::{Play, PlayWithDetails};
// }}}

pub async fn get_recent_play(
	State(state): State<AppContext>,
) -> Result<Json<PlayWithDetails>, AppError> {
	let after = Utc::now()
		.checked_sub_signed(TimeDelta::minutes(30))
		.unwrap()
		.naive_utc();

	let (play, song, chart) = state
		.ctx
		.db
		.get()?
		.prepare_cached(
			"
        SELECT 
        p.id, p.chart_id, p.user_id, p.created_at,
        p.max_recall, p.far_notes, s.score
        FROM plays p
        JOIN scores s ON s.play_id = p.id
        WHERE s.scoring_system='standard'
        AND p.user_id=?
        AND p.created_at>=?
        ORDER BY p.created_at DESC
        LIMIT 1
    ",
		)?
		.query_and_then((2, after), |row| -> Result<_, AppError> {
			let (song, chart) = state.ctx.song_cache.lookup_chart(row.get("chart_id")?)?;
			let play = Play::from_sql(chart, row)?;
			Ok((play, song, chart))
		})?
		.next()
		.ok_or_else(|| AppError::new(anyhow!("No recent plays found"), StatusCode::NOT_FOUND))??;

	// Perhaps I need to make a Serialize-only version of this type which takes refs?
	Ok(axum::response::Json(PlayWithDetails {
		play,
		song: song.clone(),
		chart: chart.clone(),
	}))
}