using System;
using System.IO.Ports;

namespace OMControl.Services;

public class SerialPortService : IDisposable
{
    private SerialPort? _serialPort;
    public bool IsOpen => _serialPort?.IsOpen == true;
    public event Action<string>? DataReceived;

    public void Open(string portName, int baudRate = 9600)
    {
        if (IsOpen) return;

        _serialPort = new SerialPort(portName, baudRate)
        {
            NewLine = "\n",
            ReadTimeout = 1000,
            WriteTimeout = 1000
        };

        _serialPort.DataReceived += OnDataReceived;
        _serialPort.Open();
    }

    public void Close()
    {
        if (_serialPort == null) return;
        _serialPort.DataReceived -= OnDataReceived;
        _serialPort.Close();
        _serialPort.Dispose();
        _serialPort = null;
    }

    public void Send(string data)
    {
        if (!IsOpen || _serialPort == null) return;
        _serialPort.WriteLine(data);
    }

    private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            var data = _serialPort?.ReadLine();
            if (data != null) DataReceived?.Invoke(data);
        }
        catch { }
    }

    public void Dispose() => Close();
}
