//! Comandos ESC/POS para impressoras térmicas 80mm
//! Comandos Epson ESC/POS padrão — funciona com TM-T20 e compatíveis.

/// Inicializar impressora
pub const INIT: &[u8] = b"\x1B\x40";
/// Nova linha
pub const LF: &[u8] = b"\x0A";
/// Cortar papel (parcial)
pub const CUT: &[u8] = b"\x1D\x56\x01";
/// Cortar papel (total)
pub const CUT_FULL: &[u8] = b"\x1D\x56\x00";
/// Alimentar 3 linhas antes de cortar
pub const FEED_CUT: &[u8] = b"\x1B\x64\x03";
/// Negrito ON / OFF
pub const BOLD_ON: &[u8] = b"\x1B\x45\x01";
pub const BOLD_OFF: &[u8] = b"\x1B\x45\x00";
/// Alinhamento
pub const ALIGN_LEFT: &[u8] = b"\x1B\x61\x00";
pub const ALIGN_CENTER: &[u8] = b"\x1B\x61\x01";
pub const ALIGN_RIGHT: &[u8] = b"\x1B\x61\x02";
/// Fonte normal / dupla
pub const FONT_NORMAL: &[u8] = b"\x1B\x21\x00";
pub const FONT_DOUBLE: &[u8] = b"\x1B\x21\x30";
/// Linha divisória (48 colunas para 80mm)
pub const DIVIDER: &str = "--------------------------------";

/// Monta texto centralizado com negrito + fonte dupla
pub fn title(text: &str) -> Vec<u8> {
    let mut out = Vec::new();
    out.extend_from_slice(ALIGN_CENTER);
    out.extend_from_slice(BOLD_ON);
    out.extend_from_slice(FONT_DOUBLE);
    out.extend_from_slice(text.as_bytes());
    out.extend_from_slice(LF);
    out.extend_from_slice(FONT_NORMAL);
    out.extend_from_slice(BOLD_OFF);
    out
}

/// Monta linha normal (alinhada à esquerda)
pub fn line(text: &str) -> Vec<u8> {
    let mut out = Vec::new();
    out.extend_from_slice(ALIGN_LEFT);
    out.extend_from_slice(text.as_bytes());
    out.extend_from_slice(LF);
    out
}

/// Monta linha centralizada
pub fn line_center(text: &str) -> Vec<u8> {
    let mut out = Vec::new();
    out.extend_from_slice(ALIGN_CENTER);
    out.extend_from_slice(text.as_bytes());
    out.extend_from_slice(LF);
    out
}

/// Monta linha em negrito
pub fn line_bold(text: &str) -> Vec<u8> {
    let mut out = Vec::new();
    out.extend_from_slice(BOLD_ON);
    out.extend_from_slice(ALIGN_LEFT);
    out.extend_from_slice(text.as_bytes());
    out.extend_from_slice(LF);
    out.extend_from_slice(BOLD_OFF);
    out
}

/// Monta linha com chave-valor alinhado (label 14 chars + espaço + valor 14 chars)
pub fn kv(label: &str, value: &str) -> Vec<u8> {
    let padded_label = format!("{:<14}", label);
    let padded_value = format!("{:>14}", value);
    let line = format!("{} {}", padded_label, padded_value);
    let line = if line.len() > 48 { line[..48].to_string() } else { line };
    let mut out = Vec::new();
    out.extend_from_slice(ALIGN_LEFT);
    out.extend_from_slice(line.as_bytes());
    out.extend_from_slice(LF);
    out
}

/// Monta linha divisória
pub fn divider() -> Vec<u8> {
    let mut out = Vec::new();
    out.extend_from_slice(ALIGN_LEFT);
    out.extend_from_slice(DIVIDER.as_bytes());
    out.extend_from_slice(LF);
    out
}

/// Monta espaço em branco (N linhas)
pub fn blank_lines(n: u8) -> &'static [u8] {
    const BLANK: &[u8] = b"\n\n\n\n\n\n\n\n";
    &BLANK[..(n as usize).min(8)]
}
