namespace HistoryView.Data;

public partial class Mini8Info(IEnableDeviceNotify? enableDevice) : ObservableObject
{
    [ObservableProperty]
    private byte _index;
    [ObservableProperty]
    private string? _Name;
    [ObservableProperty]
    private string? _Address;
    [ObservableProperty]
    private int _Port;
    [ObservableProperty]
    private bool _Enable;
    [ObservableProperty]
    private Mini8Status _Status;

    [ObservableProperty]
    private bool _IsConnected;

    partial void OnEnableChanging(bool value)
    {
        enableDevice?.EnableDevice(this.Index, value);
    }
}

public interface IEnableDeviceNotify
{
    void EnableDevice(byte mini8Index, bool isEnable);
}

public delegate void PVChanged(float pv, DateTime changeTime);

public partial class Channel : ObservableObject
{
    partial void OnPVChanged(float value)
    {
        if (this.Inhibit == Inhibit.Disable)
        {
            this.Status = ChannelSuatus.Normal;
            return;
        }

        if (this.ChannelMode==ChannelMode.UnUsed)
        {
            this.Status = ChannelSuatus.Normal;
            return;
        }

        if (this.SensorBreakAlarm == TcBorken.Error)
        {
            this.Status = ChannelSuatus.Error;
            return;
        }

        DateTime time = DateTime.Now;
        PVRingBuffer.Insert(value);
        DateTimeRingBuffer.Insert(time);
        this.OnPVChangedEvent?.Invoke(value, time);

        if (this.ChannelMode == ChannelMode.Monitor)
        {
            this.Status = ChannelSuatus.Normal;
            return;
        }

        if (!value.InRange(Floor, Caps))
        {
            this.Status = ChannelSuatus.Error;
            return;
        }

        if (!value.InRange(FloorWarning, CapsWarning))
        {
            this.Status = ChannelSuatus.Warning;
            return;
        }

        this.Status = ChannelSuatus.Normal;
    }

    public byte Mini8Index { get; set; }
    public byte ChannelIndex { get; set; }

    public event PVChanged? OnPVChangedEvent;
    public readonly RingBuffer<float> PVRingBuffer = new(120);
    public readonly RingBuffer<DateTime> DateTimeRingBuffer = new(120);


    [ObservableProperty]
    private string? _Name;

    [ObservableProperty]
    private float _Caps;
    [ObservableProperty]
    private float _Floor;
    [ObservableProperty]
    private float _CapsWarning;
    [ObservableProperty]
    private float _FloorWarning;

    [ObservableProperty]
    private ChannelSuatus _Status;

    [ObservableProperty]
    private ChannelMode _ChannelMode;

    [ObservableProperty]
    private float _PV;
    [ObservableProperty]
    private float _WorkingOutput;
    [ObservableProperty]
    private AutoTuneStatus _AutoTuneStatus;

    [ObservableProperty]
    private float _AutoTune_P;
    [ObservableProperty]
    private float _AutoTune_I;
    [ObservableProperty]
    private float _AutoTune_D;

    [ObservableProperty]
    private TcBorken _SensorBreakAlarm;

    [ObservableProperty]
    private float _SetPoint;

    [ObservableProperty]
    private ActiveTuneSet _ActiveTuneSet;

    [ObservableProperty]
    private float _Running_P;
    [ObservableProperty]
    private float _Running_I;
    [ObservableProperty]
    private float _Running_D;

    [ObservableProperty]
    private Inhibit _Inhibit;

    [ObservableProperty]
    private float _SetpointUpRate;
    [ObservableProperty]
    private float _SetpointDownRate;
}

public enum Mini8Status
{
    Unknow,
    Normal,
    Error,
    Warning,
    LostConnection,
    Disabled
}

public enum ChannelSuatus
{
    Normal,
    Error,
    Warning,
}