use colornamer::{ColorNamer, Colors};

use crate::genetics::{Genetic, Transcriber};

use super::stats::Stat;

#[derive(Default)]
pub struct Coloration {
    pub eyes: Color,
    pub body: Color,
}

impl Coloration {
    pub fn profile(&self) -> String {
        return format!(
            "Eyes: {}\nBody: {}\n",
            self.eyes.to_name(),
            self.body.to_name()
        );
    }
}

impl Genetic for Coloration {
    fn transcribe(&mut self, t: Transcriber) {
        self.eyes.transcribe(t.nest("eyes"));
        self.body.transcribe(t.nest("body"));
    }
}

#[derive(Clone, Default)]
pub struct Color {
    pub r: Stat<'.', '!', 0, 8>,
    pub g: Stat<'.', '!', 0, 8>,
    pub b: Stat<'.', '!', 0, 8>,
    pub p: Stat<'.', '!', 0, 8>,
}

impl Genetic for Color {
    fn transcribe(&mut self, t: Transcriber) {
        self.r.transcribe(t.nest("r"));
        self.g.transcribe(t.nest("g"));
        self.b.transcribe(t.nest("b"));
        self.p.transcribe(t.nest("p"));
    }
}

impl Color {
    pub fn to_rgb(&self) -> (u8, u8, u8) {
        let mut r = self.r.value() * 255 / 8;
        let mut g = self.g.value() * 255 / 8;
        let mut b = self.b.value() * 255 / 8;
        let p = self.p.value() * 255 / 8;

        r = (r * (255 - p) + 0xd0 * p) / 255;
        g = (g * (255 - p) + 0xd0 * p) / 255;
        b = (b * (255 - p) + 0xd8 * p) / 255;
        return (r as u8, g as u8, b as u8);
    }
    pub fn to_name(&self) -> String {
        let colornamer = ColorNamer::new(Colors::NTC);
        let (r, g, b) = self.to_rgb();
        let hex_color = format!("#{:02x}{:02x}{:02x}", r, g, b);
        return format!(
            "{} ({})",
            colornamer.name_hex_color(&hex_color).unwrap(),
            hex_color
        );
    }
}
