use sha2::{Digest, Sha256};
use crate::types::Prescription;
pub fn compute_hash(rx: &Prescription) -> String {
let drug_names: Vec<&str> = rx.medications.iter().map(|m| m.drug.as_str()).collect();
let payload = format!(
"{}|{}|{}|{}",
rx.patient.name,
rx.prescriber.name,
drug_names.join(","),
rx.date,
);
let mut hasher = Sha256::new();
hasher.update(payload.as_bytes());
format!("{:x}", hasher.finalize())
}
pub fn build_qr_payload(id: &str, hash: &str, timestamp: &str) -> String {
format!("labscript:v1:{id}:{hash}:{timestamp}")
}
pub fn render_qr_text(payload: &str) -> Result<Vec<String>, crate::errors::LabscriptError> {
use qrcode::QrCode;
let code = QrCode::new(payload.as_bytes())
.map_err(|e| crate::errors::LabscriptError::Pdf(format!("QR generation failed: {e}")))?;
let width = code.width();
let modules: Vec<Vec<bool>> = (0..width)
.map(|y| {
(0..width)
.map(|x| code[(x, y)] == qrcode::Color::Dark)
.collect()
})
.collect();
let mut lines = Vec::new();
let mut y = 0;
while y < width {
let mut line = String::new();
for x in 0..width {
let top = modules[y][x];
let bottom = if y + 1 < width {
modules[y + 1][x]
} else {
false
};
let ch = match (top, bottom) {
(true, true) => '\u{2588}', (true, false) => '\u{2580}', (false, true) => '\u{2584}', (false, false) => ' ',
};
line.push(ch);
}
lines.push(line);
y += 2;
}
Ok(lines)
}