using FinsTcp;
using ProtocalGeneral;

namespace MinicsConsole.Connector;

public class PLCNotifier(HardwareAddress address, ILog log) : IMini8DataNotifier, ITcpConnectNority, IDisposable
{
    private readonly Fins_Tcp _fins = new();
    public string Name { get; set; } = "PLC Fins Tcp";

    public bool StartService()
    {
        if (address.PLCAddress is null)
            return false;
        if (string.IsNullOrEmpty(address.PLCAddress.IPAddress))
            return false;

        this._fins.Initialize(this);
        this._fins.Connect(address.PLCAddress.IPAddress, address.PLCAddress.Port, PlcHeartBeatCallBack);

        return true;
    }


    public void Dispose()
    {
        this._fins?.Dispose();
    }

    private bool PlcHeartBeatCallBack()
    {
        if (address.PLCAddress is null)
            return true;

        if (string.IsNullOrEmpty(address.PLCAddress.HeartBeatAddress))
            return true;

        try
        {
            return _fins.SetData<bool>(address.PLCAddress.HeartBeatAddress, true);
        }
        catch
        {
            return false;
        }
    }

    void IMini8DataNotifier.ChannelInfoNotify(byte mini8, byte channel, ChannelData channelData)
    {
        if (this._fins is null)
            return;

        if (!this._PlcConnected)
            return;

        if (!address.PLCChannelsAddresses.TryGetSubValue(mini8, channel, out ChannelAddressPLC? channelAddress) || channelAddress is null)
            return;

        if (string.IsNullOrEmpty(channelAddress.PV))
            return;


        if (!this._fins.SetData(channelAddress.PV, channelData.PV))
            log.Warning($"PLCNotifier ChannelInfoNotify Send Mini8 - {mini8} channel {channel} PV {channelData.PV} Failed");
    }
    private bool _PlcConnected = false;


    void ITcpConnectNority.Connect(string ip, int port)
    {
        this._PlcConnected = true;
        log.Info($"PLC Connected {ip}:{port}");
    }

    void ITcpConnectNority.DisConnect(string ip, int port)
    {
        this._PlcConnected = false;
        log.Warning($"PLC Disconnected {ip}:{port}");
    }

    void IMini8DataNotifier.AlarmNotify(byte mini8, byte channel, float temperature)
    {
    }

    void IMini8DataNotifier.AlarmTcBrockenNotify(byte mini8, byte channel)
    {
    }

    void IMini8DataNotifier.Mini8ConnectNotify(byte mini8, bool connected)
    {
    }
}