<?php

declare(strict_types=1);

namespace Atdt;

/**
 * ANSI output builder (SPEC §9.4 Ctx::out()). Fluent, tiny, emits only
 * sequences the client parser supports (§7.3).
 */
final class Ansi
{
    private string $buf = '';

    public static function make(): self
    {
        return new self();
    }

    /** Clear screen + home. */
    public function cls(): self
    {
        $this->buf .= "\x1b[2J\x1b[H";
        return $this;
    }

    /** Cursor to 1-based row, col. */
    public function at(int $row, int $col): self
    {
        $this->buf .= "\x1b[" . max(1, $row) . ';' . max(1, $col) . 'H';
        return $this;
    }

    /** Foreground 0–15 in VGA order (8–15 = bright). */
    public function fg(int $n): self
    {
        $n = max(0, min(15, $n));
        $this->buf .= $n < 8
            ? "\x1b[22;" . Pipe::VGA_TO_SGR[$n] . 'm'
            : "\x1b[1;" . Pipe::VGA_TO_SGR[$n - 8] . 'm';
        return $this;
    }

    /** Background 0–7 in VGA order. */
    public function bg(int $n): self
    {
        $this->buf .= "\x1b[" . (Pipe::VGA_TO_SGR[max(0, min(7, $n))] + 10) . 'm';
        return $this;
    }

    public function blink(bool $on = true): self
    {
        $this->buf .= $on ? "\x1b[5m" : "\x1b[25m";
        return $this;
    }

    /** SGR reset: fg 7, bg 0, attributes off. */
    public function reset(): self
    {
        $this->buf .= "\x1b[0m";
        return $this;
    }

    /** Raw text (already Unicode; must not contain ESC of its own). */
    public function txt(string $s): self
    {
        $this->buf .= $s;
        return $this;
    }

    /** Render a pipe-coded string with MCI vars (§8.5) into the stream. */
    public function pipe(string $s, array $vars = []): self
    {
        $this->buf .= Pipe::render($s, $vars);
        return $this;
    }

    /** CRLF. */
    public function nl(int $count = 1): self
    {
        $this->buf .= str_repeat("\r\n", max(1, $count));
        return $this;
    }

    public function str(): string
    {
        return $this->buf;
    }
}
