using System.Net.Sockets;

namespace EpsonReceiptPrinter;

public sealed class EpsonNetworkReceiptPrinter : IReceiptPrinter
{
    private readonly string _host;
    private readonly int _port;
    private readonly PrinterCodePage _codePage;

    public EpsonNetworkReceiptPrinter(string host, int port = 9100, PrinterCodePage codePage = PrinterCodePage.PC865_Nordic)
    {
        if (string.IsNullOrWhiteSpace(host))
        {
            throw new ArgumentException("Host must be provided.", nameof(host));
        }

        _host = host;
        _port = port;
        _codePage = codePage;
    }

    public async Task PrintAsync(Receipt receipt, CancellationToken cancellationToken = default)
    {
        ArgumentNullException.ThrowIfNull(receipt);

        var data = ReceiptFormatter.Format(receipt, _codePage);
        await PrintRawAsync(data, cancellationToken);
    }

    public async Task PrintRawAsync(byte[] data, CancellationToken cancellationToken = default)
    {
        ArgumentNullException.ThrowIfNull(data);

        using var client = new TcpClient();
        await client.ConnectAsync(_host, _port, cancellationToken);

        await using var stream = client.GetStream();
        await stream.WriteAsync(data, cancellationToken);
        await stream.FlushAsync(cancellationToken);
    }
}
