namespace MinicsConsole.Helper.RawDataFilter;

public class AlarmHelperLayer(byte mini8Index, ILog log, BasicInfo basicInfo, Mini8DataDispatcher dataDispatcher) : IMini8DataFilter
{
    public IDataSender? NextSender { get; set; }
    public ChannelDataBaseHelper? DataBaseHelper { get; set; }

    private readonly ConcurrentDictionary<byte, DateTime> _ErrorRecord = [];

    private bool AlarmDelayCheck(Mini8Output mini8Output, ChannelData channelData)
    {
        if (channelData.Caps <= channelData.Floor)
            return false;

        if (mini8Output.PV.InRange(channelData.Floor, channelData.Caps))
        {
            _ErrorRecord.Remove(mini8Output.ChannelIndex, out _);
            return false;
        }

        if (_ErrorRecord.TryAdd(mini8Output.ChannelIndex, mini8Output.CollectTime))
            return false;

        TimeSpan alarmInverval = mini8Output.CollectTime - _ErrorRecord[mini8Output.ChannelIndex];
        if (alarmInverval > TimeSpan.FromSeconds(basicInfo.AlarmDelaySeconds))
            return true;

        return false;
    }

    bool IDataSender.Send(Mini8Output mini8Output, ChannelData channelData, object? s)
    {
        switch (channelData.ChannelMode)
        {
            case ChannelMode.Control:
                break;
            case ChannelMode.Monitor:
            case ChannelMode.UnUsed:
                return true;
            default:
                //log.Warning($"Mini8 - {mini8Index} - Channel {mini8Output.ChannelIndex} Unknow Channel Mode: {(byte)channelData.ChannelMode}");
                return true;
        }

        switch (mini8Output.SensorBreakAlarm)
        {
            case TcBorken.Normal:
                break;
            case TcBorken.Error:
                dataDispatcher.AlarmTcBrockenNotify(mini8Index, mini8Output.ChannelIndex);
                DataBaseHelper?.InsertDB_TcAlarm(channelData, mini8Output);
                return true;
            default:
                log.Warning($"Mini8 - {mini8Index} - Channel {mini8Output.ChannelIndex} Unknow TC status: {(byte)mini8Output.SensorBreakAlarm}");
                return true;
        }

        if (this.AlarmDelayCheck(mini8Output, channelData))
        {
            dataDispatcher.AlarmNotify(mini8Index, mini8Output.ChannelIndex, mini8Output.PV);
            DataBaseHelper?.InsertDB_TempAlarm(channelData, mini8Output);
        }

        return true;
    }
}