use anyhow::{bail, Result};
use image::Rgba;
use rand::Rng;

#[derive(Debug, Clone, Copy)]
pub struct RgbColor {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

impl RgbColor {
    pub fn to_rgba(self) -> Rgba<u8> {
        Rgba([self.r, self.g, self.b, 255])
    }

    pub fn inverse(self) -> Self {
        RgbColor {
            r: 255 - self.r,
            g: 255 - self.g,
            b: 255 - self.b,
        }
    }
}

pub fn parse_hex_color(hex: &str) -> Result<RgbColor> {
    if hex.len() != 6 || !hex.chars().all(|c| c.is_ascii_hexdigit()) {
        bail!("Color must be a 6-digit hex value without '#', e.g. ffffff");
    }

    let r = u8::from_str_radix(&hex[0..2], 16)?;
    let g = u8::from_str_radix(&hex[2..4], 16)?;
    let b = u8::from_str_radix(&hex[4..6], 16)?;

    Ok(RgbColor { r, g, b })
}

pub fn random_color() -> RgbColor {
    let mut rng = rand::thread_rng();
    RgbColor {
        r: rng.gen_range(0..=255),
        g: rng.gen_range(0..=255),
        b: rng.gen_range(0..=255),
    }
}
