use super::{kind::Kind, Protostar};
use fastrand::Rng;
use strum::{EnumIter, IntoEnumIterator};

impl Protostar {
    pub fn generate_description(&self, kind: &Kind, seed: u64) -> String {
        let mut rng = Rng::with_seed(seed);
        let kind_name = match kind {
            Kind::Planet => "planet",
            Kind::Star => "star",
            Kind::Nova => "nova",
            Kind::Banana => "banana shaped planet",
            Kind::Station => "space station",
        };

        let size_multiplier = rng.u16(0..u16::MAX);
        let size_compare_item = rng.choice(comparison_items()).unwrap_or("ohio".into());

        let life = rng.choice(Life::iter()).unwrap_or(Life::NoLife);
        let life_description = rng
            .choice(life.descriptions())
            .unwrap_or("sensor sweep for life failed".to_string());

        let danger_warning = rng
            .choice(ThreatLevel::iter())
            .unwrap_or(ThreatLevel::Boring)
            .warning();

        let description = format!(
            "this {kind_name} is about {size_multiplier} times the size of {size_compare_item}.
            {life_description}
            {danger_warning}
            "
        );
        description.into()
    }
}

fn comparison_items() -> Vec<String> {
    let results = items();
    let mut results = results
        .iter()
        .map(|s| s.to_string())
        .collect::<Vec<String>>();

    // add actions
    for actor in actors().iter() {
        for posession in posessions().iter() {
            results.push(format!("the {posession} of {actor}"));
        }
    }
    results
}

fn actors() -> Vec<&'static str> {
    vec![
        "a manatee",
        "a machine",
        "an artist",
        "a small kobold",
        "a large kobold",
        "a kittycat",
        "a worm",
        "a dog",
        "a shrimp",
        "a tiger",
        "an elephant",
        "an engineer",
        "a clown",
        "a prawn",
        "a monster",
        "an actor",
        "a celebrity",
        "a singer",
        "a conductor",
        "a firefighter",
        "a president",
        "a farmer",
        "a queen",
        "an ant",
        "a kitten",
        "a dragon",
        "a sloth",
        "a monkey",
        "a brain in a jar",
        "a seashell",
        "a lobster",
        "a crab",
        "a shark",
        "a programmer",
        "a janitor",
        "an iguana",
        "a child",
        "an astronaut",
        "an ai",
        "an android",
        "famous actor bela lugosi",
        "famous actor bruce lee",
        "famous actor irrfan khan",
        "famous actor james avery",
        "famous actor patrick stewart",
        "famous author terry pratchett",
        "famous author douglas adams",
        "famous author neil gaiman",
        "forgotten video game mascot polygon man",
        "forgotten video game mascot segata sanshiro",
        "a perfectly spherical cow",
        "alice",
        "bob",
        "mallory",
    ]
}

fn posessions() -> Vec<&'static str> {
    vec![
        "dreams",
        "hopes",
        "aspirations",
        "sleepyness",
        "fanbase",
        "home",
        "beliefs",
        "honesty",
        "belief",
        "love",
        "justifications",
        "breakdancing ability",
        "ability",
        "memory",
    ]
}

fn items() -> Vec<&'static str> {
    vec![
        "florida",
        "a pack of rats",
        "the eiffel tower",
        "ohio",
        "texas",
        "a baseball field",
        "a football field (american)",
        "a football field (european)",
        "a ford f-150",
        "a 1:3900 scale replica of the starship voyager",
        "the potassium atoms in a banana",
        "the great pyramid of giza",
        "a small boulder the size of a large boulder",
        "a large boulder the size of a small boulder",
        "a banana (for scale)",
        "a pebble",
        "a basketball court",
        "100,000,000,000$ in small and unmarked bills",
        "a box of donuts",
        "zeng jinlian, the tallest woman ever as reported by guiness world records",
        "a candle",
        "a box of of chocolates",
        "an airbus A318",
        "an embraer ERJ135",
        "a fairchild dornier 328-300JET",
        "a sunflower",
        "a pebble",
        "the great wall of china",
        "a funny joke",
        "an unfunny joke",
        "the oldest joke",
        "france",
        "china",
        "hawaii",
        "the kīlauea lighthouse",
        "the forbidden city",
        "bowl of hot soup",
        "a cold drink",
    ]
}

#[derive(EnumIter)]
pub enum ThreatLevel {
    Boring,
    Harmless,
    MostlyHarmless,
    SlightlyDangerous,
    Dangerous,
    CertainDeath,
}

impl ThreatLevel {
    pub fn warning(&self) -> &'static str {
        match self {
            ThreatLevel::Boring => "it's a bit boring here.",
            ThreatLevel::Harmless => "this place is harmless.",
            ThreatLevel::MostlyHarmless => "this place is mostly harmless.",
            ThreatLevel::SlightlyDangerous => "this place is slightly dangerous! watch out!",
            ThreatLevel::Dangerous => "this place is seriously messed up! don't go here!",
            ThreatLevel::CertainDeath => "this place means certain death! STAY CLEAR!",
        }
    }
}

#[derive(EnumIter)]
pub enum Life {
    NoLife,
    LifePossible,
    Primitive,
    Intelligent,
}

impl Life {
    pub fn descriptions(&self) -> Vec<String> {
        match self {
            Life::NoLife => no_life_descriptions(),
            Life::LifePossible => life_possible_description(),
            Life::Primitive => primitive_life_description(),
            Life::Intelligent => intelligent_life_description(),
        }
    }
}

fn no_life_descriptions() -> Vec<String> {
    vec!["life is not possible here..."]
        .iter()
        .map(|s| s.to_string())
        .collect::<Vec<String>>()
}

fn life_possible_description() -> Vec<String> {
    vec![
        "life seems possible but our sensors aren't picking anything up.",
        "our sensor sweep for life failed.",
    ]
    .iter()
    .map(|s| s.to_string())
    .collect::<Vec<String>>()
}

fn primitive_life_description() -> Vec<String> {
    vec!["our sensors are picking up single celled lifeforms."]
        .iter()
        .map(|s| s.to_string())
        .collect::<Vec<String>>()
}

fn intelligent_life_description() -> Vec<String> {
    let mut results = vec![];
    for inhabitant in inhabitants().iter() {
        for action in inhabitant_actions().iter() {
            results.push(format!(
                "our life sensors have picked up {inhabitant} {action}"
            ))
        }
    }
    results
}

fn inhabitants() -> Vec<&'static str> {
    vec![
        "strange creatures",
        "clowns",
        "androids",
        "slime people",
        "sea creatures",
        "lizards",
        "hamsters",
        "mice",
        "dolphins",
        "fish",
        "crows",
        "snakes",
        "snake monsters",
        "dragons",
        "kobolds",
        "tentacle monsters",
        "rats",
        "vampires",
        "spooky skeletons",
        "punks",
        "werewolfs",
        "minotaurs",
        "ghouls",
        "krakens",
        "eldritch horrors",
        "tadpoles",
        "frog people",
        "beings made of smoke",
        "ghosts",
        "scary monsters",
        "ancient romans",
        "cool guys with sunglasses and leather jackets",
        "clones of you",
    ]
}

fn inhabitant_actions() -> Vec<&'static str> {
    vec![
        "who throw rocks at intruders.",
        "who like to make music.",
        "who like to climb.",
        "who like to swim.",
        "who program computers.",
        "who bake.",
        "who make dangerous potions.",
        "who like to collect rocks.",
        "who like to write strongly worded letters.",
        "who scare off intruders by debating politics with them.",
        "who like to make lifelike chocolate statues.",
        "who grow soap on trees!",
        "who like to make video games.",
        "who like to sleep all day!",
        "who like to watch anime.",
        "who drive expensive cars!",
        "who collect little figures.",
        "who start projects but never finish them.",
        "who like to play video games.",
        "who like to paint each others nails.",
        "who like to swim in clear lakes.",
        "who grow their own tomatoes.",
        "who fall asleep on the train.",
        "who tell each other lies for fun.",
        "who pirate music.",
        "who like to sleep on warm rocks.",
        "who think digital watches are cool.",
        "who like to repair electronics.",
        "who like to repair machines.",
        "who give visitors a little kiss on the forehead.",
        "who forget to drink enough water.",
        "who are too sleepy to do anything today.",
        "who want to achieve more in life.",
        "who like to braid each others hair.",
        "who watch movies together.",
        "who like to fly model airplanes.",
        "who are trying to get over their social media addiction.",
        "who are waiting for the year of linux on the desktop.",
    ]
}
