using RioJoy.Core.Serial;

namespace RioJoy.Core.Plasma;

/// <summary>
/// Drives the plasma / VFD text display over its (secondary) serial transport,
/// writing the ESC sequences built by <see cref="PlasmaCommands"/>. Thin async
/// wrapper around an <see cref="IRioTransport"/>; the display is write-only. The
/// content shown is per-profile (Phase 5+).
/// </summary>
public sealed class PlasmaDisplay
{
    private readonly IRioTransport _transport;

    public PlasmaDisplay(IRioTransport transport)
    {
        _transport = transport ?? throw new ArgumentNullException(nameof(transport));
    }

    public Task ClearAsync(CancellationToken ct = default) =>
        WriteAsync(PlasmaCommands.Clear(), ct);

    public Task CursorHomeAsync(CancellationToken ct = default) =>
        WriteAsync(PlasmaCommands.CursorHome(), ct);

    public Task TextAsync(string text, CancellationToken ct = default) =>
        WriteAsync(PlasmaCommands.Text(text), ct);

    /// <summary>
    /// Position the cursor, set attribute + font, and write text — the
    /// <c>PlasmaPosText</c> sequence (auto-fit via
    /// <see cref="PlasmaCommands.ResolvePosText"/>). Pass (0,0) to auto-center.
    /// </summary>
    public async Task PosTextAsync(
        string text, byte x = 0, byte y = 0, byte attr = 0, byte font = 0,
        CancellationToken ct = default)
    {
        if (string.IsNullOrEmpty(text))
            return;

        (byte rx, byte ry, byte rfont, int len) = PlasmaCommands.ResolvePosText(text, x, y, font);

        await WriteAsync(PlasmaCommands.CursorX(rx), ct).ConfigureAwait(false);
        await WriteAsync(PlasmaCommands.CursorY(ry), ct).ConfigureAwait(false);
        await WriteAsync(PlasmaCommands.FontAttr(attr), ct).ConfigureAwait(false);
        await WriteAsync(PlasmaCommands.Font(rfont), ct).ConfigureAwait(false);
        await WriteAsync(PlasmaCommands.Text(text[..len]), ct).ConfigureAwait(false);
    }

    private Task WriteAsync(byte[] data, CancellationToken ct) =>
        _transport.WriteAsync(data, ct);
}
