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

use rand::Rng;

fn main() {
    let mut same_players: bool = true;
    let mut new_players: bool = true;

    while new_players {
        let mut p1: String = String::new();
        let mut p2: String = String::new();

        println!("========== PLAY DICE ==========");

        print!("Player 1: ");
        let _ = io::stdout().flush();
        io::stdin()
            .read_line(&mut p1)
            .expect("Failed to read from stdin");
        p1 = p1.trim().to_string();

        print!("Player 2: ");
        let _ = io::stdout().flush();
        io::stdin()
            .read_line(&mut p2)
            .expect("Failed to read from stdin");
        p2 = p2.trim().to_string();

        while same_players {
            let mut p1_total: i16 = 0;
            let mut p2_total: i16 = 0;

            for i in 0..5 {
                let p1_result_1: i8 = rand::thread_rng().gen_range(1..7);
                let p1_result_2: i8 = rand::thread_rng().gen_range(1..7);
                let p2_result_1: i8 = rand::thread_rng().gen_range(1..7);
                let p2_result_2: i8 = rand::thread_rng().gen_range(1..7);

                p1_total += i16::from(p1_result_1) + i16::from(p1_result_2);
                p2_total += i16::from(p2_result_1) + i16::from(p2_result_2);

                println!("========== Turn #{} ==========", i + 1);
                println!(
                    "Results: {} -> {}/6 and {}/6 VS {} -> {}/6 and {}/6",
                    p1, p1_result_1, p1_result_2, p2, p2_result_1, p2_result_2
                );
                if p1_total == p2_total {
                    println!("Total..: {} -> {} and {} -> {}", p1, p1_total, p2, p2_total);
                } else if p1_total > p2_total {
                    println!(
                        "Total..: \x1b[41m{} -> {}\x1b[0m and {} -> {}",
                        p1, p1_total, p2, p2_total
                    );
                } else {
                    println!(
                        "Total..: {} -> {} and \x1b[41m{} -> {}\x1b[0m",
                        p1, p1_total, p2, p2_total
                    );
                }
            }

            if p1_total == p2_total {
                println!("Draw!");
            } else if p1_total > p2_total {
                println!(
                    "\x1b[32mThe winner is {} with {} points!\x1b[0m",
                    p1, p1_total
                );
            } else {
                println!(
                    "\x1b[32mThe winner is {} with {} points!\x1b[0m",
                    p2, p2_total
                );
            }

            new_players = false;

            println!("What do you want to do?");
            println!("  Replay with the same players (R)");
            println!("  Replay with new players (N)");
            println!("  Quit (any other key)");

            let mut choice: String = String::new();
            print!("Your choice: ");
            let _ = io::stdout().flush();
            io::stdin()
                .read_line(&mut choice)
                .expect("Failed to read from stdin");
            choice = choice.trim().to_ascii_lowercase().to_string();

            match choice.as_str() {
                "r" => {
                    same_players = true;
                    print!("\x1b[2J\x1b[H");
                }
                "n" => {
                    same_players = true;
                    new_players = true;
                    print!("\x1b[2J\x1b[H");
                    break;
                }
                _ => {
                    same_players = false;
                    new_players = false;
                }
            }
        }
    }
}
