using System;
using SimpleCore.Library;
using StandardScene.Signal.Model;

namespace StandardScene.Signal.Plc
{
    /// <summary>
    /// 单个工位运行态（不进 JSON）。扫车改写目标写状态，PLC Worker 负责下发 BOOL（或旧一字节枚举）。
    /// </summary>
    public sealed class PlcStationRuntime
    {
        private SignalWriteValue _writeSignal;
        private SignalReadValue _readSignal;
        private SignalWriteValue _readWriteSignal;

        public PlcStationRuntime(PlcStationModel station, PlcStationDockModel dock, object sync = null)
        {
            Station = station ?? throw new ArgumentNullException(nameof(station));
            Dock = dock ?? throw new ArgumentNullException(nameof(dock));
            Sync = sync ?? new object();
        }

        public PlcStationModel Station { get; }

        public PlcStationDockModel Dock { get; }

        /// <summary>兼容旧代码：机构连接配置（不含工位地标）。</summary>
        public PlcStationModel Config => Station;

        public object Sync { get; }

        public string JgName => Station.JgName ?? "";

        public string DockId => Dock.ResolvedDockId;

        public string DisplayName =>
            string.IsNullOrEmpty(DockId) || string.Equals(DockId, PlcConfigLoader.DefaultDockId, StringComparison.OrdinalIgnoreCase)
                ? JgName
                : $"{JgName}/{DockId}";

        public SignalReadValue ReadSignal
        {
            get => _readSignal;
            set
            {
                if (_readSignal != value)
                    Diagnosis.Log($"{DisplayName} 读信号 {_readSignal} → {value}", "PLC", true);
                _readSignal = value;
            }
        }

        public SignalWriteValue WriteSignal
        {
            get => _writeSignal;
            set
            {
                if (_writeSignal != value)
                    Diagnosis.Log($"{DisplayName} 写信号 {_writeSignal} → {value}", "PLC", true);
                _writeSignal = value;
                WriteSuccess = false;
            }
        }

        public SignalWriteValue ReadWriteSignal
        {
            get => _readWriteSignal;
            set
            {
                if (_readWriteSignal != value)
                    Diagnosis.Log($"{DisplayName} 回读写值 {_readWriteSignal} → {value}", "PLC", true);
                _readWriteSignal = value;
            }
        }

        public int InAgvNo { get; set; }

        public int RequestInAgvNo { get; set; }

        public bool IsConnected { get; set; }

        public bool WriteSuccess { get; set; }

        public bool Heart { get; set; }

        public string LastError { get; set; } = "";

        public PlcStationSnapshot ToSnapshot() => new PlcStationSnapshot
        {
            JgName = DisplayName,
            IsConnected = IsConnected,
            ReadSignal = ReadSignal.ToString(),
            WriteSignal = WriteSignal.ToString(),
            ReadWriteSignal = ReadWriteSignal.ToString(),
            InAgvNo = InAgvNo,
            RequestInAgvNo = RequestInAgvNo,
            WriteSuccess = WriteSuccess,
            Heart = Heart,
            LastError = LastError ?? ""
        };
    }
}
