use std::{collections::BTreeMap, io::{self, Write}};

fn main() {
    let mut article_price: f32 = 0.0;
    let mut paid_price: f32 = 0.0;
    let mut money: BTreeMap<String, f32> = BTreeMap::new();
    money.insert("0.05".to_string(), 0.0);
    money.insert("0.10".to_string(), 0.0);
    money.insert("0.25".to_string(), 0.0);
    money.insert("0.50".to_string(), 0.0);
    money.insert("1".to_string(), 0.0);
    money.insert("2".to_string(), 0.0);
    money.insert("5".to_string(), 0.0);
    money.insert("10".to_string(), 0.0);
    money.insert("20".to_string(), 0.0);
    money.insert("50".to_string(), 0.0);
    money.insert("100".to_string(), 0.0);

    let mut is_int: bool = false;
    while !is_int {
        print!("Please enter the article's price: ");
        let _ = io::stdout().flush();
        let mut input_text: String = String::new();
        io::stdin()
            .read_line(&mut input_text)
            .expect("Failed to read from stdin");
        match input_text.trim().parse::<f32>() {
            Ok(i) => {
                is_int = true;
                article_price = i;
            }
            Err(..) => println!("Must be a number!"),
        }
    }

    is_int = false;
    while !is_int {
        print!("Amount given by the customer: ");
        let _ = io::stdout().flush();
        let mut input_text: String = String::new();
        io::stdin()
            .read_line(&mut input_text)
            .expect("Failed to read from stdin");
        match input_text.trim().parse::<f32>() {
            Ok(i) => {
                is_int = true;
                paid_price = i;
            }
            Err(..) => println!("Must be a number!"),
        }
    }

    if paid_price < article_price {
        println!("The customer has not given enough monney!!");
        println!("Press enter to continue...");
        let mut buffer = String::new();
        std::io::stdin()
            .read_line(&mut buffer)
            .expect("Failed to read line");
        return;
    }

    let mut remain = paid_price - article_price;
    let mut change = remain;

    for (k, v) in money.iter_mut().rev() {
        let denomination :f32 = k.parse::<f32>().unwrap();
        let denom_val = (remain / denomination).floor();
        *v = denom_val;
        remain -= denom_val * denomination;
    }
    if remain >= 0.03 {
        change += 0.05;
    }
    else {
        change -= remain;
    }

    println!("You have to give them {:.2} $, So:", change);
    
    let mut total = 0.0;
    for (k, v) in money.iter().rev() {
        if *v != 0.0 {
            println!("{} X {} $", v, k);
            total += v;
        }
    }
    println!("This makes a total of {:.0} coins and bills", total);

    println!("Press enter to continue...");
        let mut buffer = String::new();
        std::io::stdin()
            .read_line(&mut buffer)
            .expect("Failed to read line");
        return;
}
