use qrcode::QrCode;
use qrcode::render::svg;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
static BATTLE_PIN_COUNTER: AtomicU64 = AtomicU64::new(1013);
#[must_use]
pub fn generate_battle_pin() -> String {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos();
let count = BATTLE_PIN_COUNTER.fetch_add(7919, Ordering::Relaxed);
#[allow(clippy::cast_possible_truncation)]
let val = ((nanos ^ (u128::from(count) * 1_000_003)) % 900_000 + 100_000) as u32;
format!("{val:06}")
}
pub fn generate_qr_svg(payload: &str) -> Result<String, String> {
let code =
QrCode::new(payload.as_bytes()).map_err(|e| format!("Failed to generate QR code: {e}"))?;
let svg_xml = code
.render::<svg::Color>()
.min_dimensions(200, 200)
.dark_color(svg::Color("#4a3828"))
.light_color(svg::Color("#fbf8f2"))
.build();
Ok(svg_xml)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_battle_pin_format() {
let pin = generate_battle_pin();
assert_eq!(pin.len(), 6);
assert!(pin.chars().all(|c| c.is_ascii_digit()));
}
#[test]
fn test_generate_qr_svg_produces_svg() {
let svg = generate_qr_svg("https://example.com/battle?pin=123456").unwrap();
assert!(svg.contains("<svg"));
assert!(svg.contains("</svg>"));
assert!(svg.contains("#4a3828"));
}
}