use gtk::{gio, prelude::*};

pub fn linkify(input: &str) -> String {
    let finder = linkify::LinkFinder::new();

    finder.spans(input).fold(String::new(), |acc, span| {
        let append = match span.kind() {
            Some(&linkify::LinkKind::Url) => {
                format!(r"<a href='{}'>{}</a>", span.as_str(), span.as_str())
            }
            Some(&linkify::LinkKind::Email) => {
                format!(r"<a href='mailto:{}'>{}</a>", span.as_str(), span.as_str())
            }
            None => span.as_str().to_owned(),
            _ => span.as_str().to_owned(),
        };
        acc + &append
    })
}

pub fn scan(screenshot: &gio::File) -> anyhow::Result<String> {
    let (data, _) = screenshot.load_contents(gio::Cancellable::NONE)?;

    scan_bytes(&data)
}

pub fn scan_bytes(data: &[u8]) -> anyhow::Result<String> {
    let img = image::load_from_memory(data)?.into_luma8();
    let mut prepared_img = rqrr::PreparedImage::prepare(img);
    let grids = prepared_img.detect_grids();
    let mut decoded = Vec::new();

    if let Some(grid) = grids.first() {
        grid.decode_to(&mut decoded)?;
    } else {
        anyhow::bail!("Invalid QR code")
    }

    Ok(String::from_utf8(decoded)?)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn linkifi_str() {
        let uri = "hello upi://pay";
        let link = linkify(uri);
        assert_eq!(link, "hello <a href='upi://pay'>upi://pay</a>");
    }
}
