namespace MinicsConsole.Helper.RawDataFilter;

public class Mini8Provider : IMini8Provider, IMini8DataFilter
{
    public Mini8Provider(byte mini8Index, ILog log, BasicInfo basicInfo, IDictionary<byte, ChannelData> channels, Mini8DataDispatcher dataDispatcher)
    {
        this._log = log;
        this._channels = channels;
        this._mini8Index = mini8Index;
        this._dataDispatcher = dataDispatcher;
        ChannelDataBaseHelper dataBaseHelper = new(mini8Index, log);

        Mini8DataQueue mini8DataQueue = new();
        AutoApplyAutoTurnLayer applyAutoTurn = new(mini8Index, log);
        Mini8DataRecorderLayer dataRecorder = new(mini8Index, log, dataDispatcher) { DataBaseHelper = dataBaseHelper };
        AlarmHelperLayer alarmHelper = new(mini8Index, log, basicInfo, dataDispatcher) { DataBaseHelper = dataBaseHelper };

        _ = (IMini8DataFilter)this >> mini8DataQueue >> dataRecorder >> applyAutoTurn >> alarmHelper;

        this._DataBaseHelper = dataBaseHelper;
        this._ApplyAutoTurnLayer = applyAutoTurn;
    }

    private readonly ILog _log;
    private readonly byte _mini8Index;
    private readonly Mini8DataDispatcher _dataDispatcher;
    private readonly ChannelDataBaseHelper _DataBaseHelper;
    private readonly IDictionary<byte, ChannelData> _channels;
    private readonly AutoApplyAutoTurnLayer _ApplyAutoTurnLayer;


    public bool IsConnect { get; private set; } = false;
    public IDataSender? NextSender { get; set; }

    public IORM ORM { set { _DataBaseHelper.SetORM(value); } }
    public IMini8Communicator Mini8Communicator { set { _ApplyAutoTurnLayer.Sender = value; } }

    void IMini8Provider.ChannelInfoNotify(byte channel, Mini8Output mini8Output)
    {
        if (!_channels.TryGetValue(channel, out ChannelData? channelData) || channelData is null)
            return;

        this.NextSender?.Send(mini8Output, channelData, default);
    }

    void IMini8ConnectNotify.OnConnected(string IP, int port)
    {
        this.IsConnect = true;
        this._log.Info($"{IP}:{port} Connected");
        this._dataDispatcher.Mini8Connect(_mini8Index);
    }

    void IMini8ConnectNotify.OnDisconnected(string IP, int port)
    {
        this.IsConnect = false;
        this._log.Warning($"{IP}:{port} Disconnected");
        this._dataDispatcher.Mini8Disconnect(_mini8Index);
    }
}