use std::time::Duration;

use anyhow::anyhow;
// {{{ Imports
use discord_rich_presence::activity::{Activity, Assets};
use discord_rich_presence::{DiscordIpc, DiscordIpcClient};
use shimmeringmoon::arcaea::chart::Difficulty;
use shimmeringmoon::arcaea::play::PlayWithDetails;
use shimmeringmoon::arcaea::score::ScoringSystem;
use shimmeringmoon::context::paths::get_var;
use shimmeringmoon::context::Error;
// }}}

#[tokio::main]
async fn main() -> Result<(), Error> {
	let server_url = get_var("SHIMMERING_SERVER_URL")?;
	let client_id = get_var("SHIMMERING_DISCORD_ID")?;

	println!("Connecting to discord...");
	let mut ipc = DiscordIpcClient::new(&client_id).map_err(|e| anyhow!("{}", e))?;
	ipc.connect().map_err(|e| anyhow!("{}", e))?;

	println!("Starting presence loop...");
	loop {
		println!("Getting most recent score...");
		let res = reqwest::get(format!("{}/plays/latest", server_url)).await;

		let res = match res.and_then(|r| r.error_for_status()) {
			Ok(v) => v,
			Err(e) => {
				ipc.clear_activity().map_err(|e| anyhow!("{}", e))?;
				println!("{e}");

				tokio::time::sleep(Duration::from_secs(10)).await;
				continue;
			}
		};

		let triplet = res.json::<PlayWithDetails>().await?;

		let jacket_url = format!(
			"{}/jackets/by_chart_id/{}.png",
			server_url, &triplet.chart.id
		);
		println!("Jacket url: {}", jacket_url);

		let jacket_text = format!("{} — {}", &triplet.song.title, &triplet.song.artist);

		let assets = Assets::new()
			.large_image(&jacket_url)
			.large_text(&jacket_text);

		let details = format!(
			"{} [{} {}]",
			&triplet.song.title,
			Difficulty::DIFFICULTY_SHORTHANDS[triplet.chart.difficulty.to_index()],
			&triplet.chart.level,
		);

		let state = format!("{}", &triplet.play.score(ScoringSystem::Standard));
		let activity = Activity::new()
			.assets(assets)
			.details(&details)
			.state(&state);

		println!("Sending activity");
		ipc.set_activity(activity).map_err(|e| anyhow!("{}", e))?;
		tokio::time::sleep(Duration::from_secs(30)).await;
	}
}