//! Write colored text using wincon API calls

use anstyle_wincon::WinconStream as _;

fn main() -> Result<(), lexopt::Error> {
    let args = Args::parse()?;
    let stdout = std::io::stdout();
    let mut stdout = stdout.lock();

    for fixed in 0..16 {
        let style = style(fixed, args.layer, args.effects);
        let _ = print_number(&mut stdout, fixed, style);
        if fixed == 7 || fixed == 15 {
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
        }
    }

    for fixed in 16..232 {
        let col = (fixed - 16) % 36;
        if col == 0 {
            let _ = stdout.write_colored(None, None, &b"\n"[..]);
        }
        let style = style(fixed, args.layer, args.effects);
        let _ = print_number(&mut stdout, fixed, style);
    }

    let _ = stdout.write_colored(None, None, &b"\n"[..]);
    let _ = stdout.write_colored(None, None, &b"\n"[..]);
    for fixed in 232..=255 {
        let style = style(fixed, args.layer, args.effects);
        let _ = print_number(&mut stdout, fixed, style);
    }

    let _ = stdout.write_colored(None, None, &b"\n"[..]);

    Ok(())
}

fn style(
    color: impl Into<anstyle::Color>,
    layer: Layer,
    effects: anstyle::Effects,
) -> anstyle::Style {
    let color = color.into();
    (match layer {
        Layer::Fg => anstyle::Style::new().fg_color(Some(color)),
        Layer::Bg => anstyle::Style::new().bg_color(Some(color)),
        Layer::Underline => anstyle::Style::new().underline_color(Some(color)),
    }) | effects
}

fn print_number(
    stdout: &mut std::io::StdoutLock<'static>,
    fixed: u8,
    style: anstyle::Style,
) -> std::io::Result<()> {
    let fg = style.get_fg_color().and_then(|c| match c {
        anstyle::Color::Ansi(c) => Some(c),
        anstyle::Color::Ansi256(c) => c.into_ansi(),
        anstyle::Color::Rgb(_) => None,
    });
    let bg = style.get_bg_color().and_then(|c| match c {
        anstyle::Color::Ansi(c) => Some(c),
        anstyle::Color::Ansi256(c) => c.into_ansi(),
        anstyle::Color::Rgb(_) => None,
    });

    stdout
        .write_colored(fg, bg, format!("{:>3X}", fixed).as_bytes())
        .map(|_| ())
}

#[derive(Default)]
struct Args {
    effects: anstyle::Effects,
    layer: Layer,
}

#[derive(Copy, Clone, Default)]
enum Layer {
    #[default]
    Fg,
    Bg,
    Underline,
}

impl Args {
    fn parse() -> Result<Self, lexopt::Error> {
        use lexopt::prelude::*;

        let mut res = Args::default();

        let mut args = lexopt::Parser::from_env();
        while let Some(arg) = args.next()? {
            match arg {
                Long("layer") => {
                    res.layer = args.value()?.parse_with(|s| match s {
                        "fg" => Ok(Layer::Fg),
                        "bg" => Ok(Layer::Bg),
                        "underline" => Ok(Layer::Underline),
                        _ => Err("expected values fg, bg, underline"),
                    })?;
                }
                Long("effect") => {
                    const EFFECTS: [(&str, anstyle::Effects); 12] = [
                        ("bold", anstyle::Effects::BOLD),
                        ("dimmed", anstyle::Effects::DIMMED),
                        ("italic", anstyle::Effects::ITALIC),
                        ("underline", anstyle::Effects::UNDERLINE),
                        ("double_underline", anstyle::Effects::UNDERLINE),
                        ("curly_underline", anstyle::Effects::CURLY_UNDERLINE),
                        ("dotted_underline", anstyle::Effects::DOTTED_UNDERLINE),
                        ("dashed_underline", anstyle::Effects::DASHED_UNDERLINE),
                        ("blink", anstyle::Effects::BLINK),
                        ("invert", anstyle::Effects::INVERT),
                        ("hidden", anstyle::Effects::HIDDEN),
                        ("strikethrough", anstyle::Effects::STRIKETHROUGH),
                    ];
                    let effect = args.value()?.parse_with(|s| {
                        EFFECTS
                            .into_iter()
                            .find(|(name, _)| *name == s)
                            .map(|(_, effect)| effect)
                            .ok_or_else(|| {
                                format!(
                                    "expected one of {}",
                                    EFFECTS
                                        .into_iter()
                                        .map(|(n, _)| n)
                                        .collect::<Vec<_>>()
                                        .join(", ")
                                )
                            })
                    })?;
                    res.effects = res.effects.insert(effect);
                }
                _ => return Err(arg.unexpected()),
            }
        }
        Ok(res)
    }
}
