using System;
using System.Collections.Generic;

namespace CncSimulator.Device
{
    /// <summary>单台模拟设备的完整状态</summary>
    public class DeviceState
    {
        // ===== 固定信息（来自配置） =====
        /// <summary>设备编码</summary>
        public string DeviceCode { get; set; }

        /// <summary>设备描述</summary>
        public string Desc { get; set; }

        // ===== 动态状态 =====
        /// <summary>当前场景名</summary>
        public string CurrentScenario { get; set; } = "idle";

        /// <summary>是否在线（断电=false，不参与JSON生成）</summary>
        public bool IsOnline { get; set; } = true;

        /// <summary>当前NC程序名</summary>
        public string ProgramName { get; set; } = "O0001";

        /// <summary>当前零件数</summary>
        public int PartCount { get; set; } = 0;

        /// <summary>设备状态 _io_status: 0=离线, 1=在线</summary>
        public int DeviceStatus { get; set; } = 1;

        /// <summary>运行状态: 0=待机, 1=运行, 3=加工中</summary>
        public int RunStatus { get; set; } = 0;

        /// <summary>操作模式: 1=MEM, 10=JOG</summary>
        public int OperateMode { get; set; } = 1;

        /// <summary>主轴设定速度</summary>
        public decimal SpindleSpeedSet { get; set; } = 450;

        /// <summary>进给设定速度</summary>
        public decimal FeedSpeedSet { get; set; } = 60;

        /// <summary>主轴实际速度</summary>
        public decimal SpindleSpeedActual { get; set; } = 0;

        /// <summary>进给实际速度</summary>
        public decimal FeedSpeedActual { get; set; } = 0;

        /// <summary>主轴负载</summary>
        public decimal SpindleLoad { get; set; } = 0;

        /// <summary>主轴倍率</summary>
        public decimal SpindleOverride { get; set; } = 100;

        /// <summary>开机累计时间（秒）</summary>
        public decimal PowerOnTime { get; set; } = 0;

        /// <summary>运行累计时间（秒）</summary>
        public decimal RunTime { get; set; } = 0;

        /// <summary>切削累计时间（秒）</summary>
        public decimal CuttingTime { get; set; } = 0;

        /// <summary>循环时间（秒）</summary>
        public decimal CycleTime { get; set; } = 0;

        /// <summary>加工状态: G01/G00/G02/等</summary>
        public string MachiningStatus { get; set; } = "";

        /// <summary>加工程序内容片段</summary>
        public string ProgramContent { get; set; } = "";

        // ===== 剧本控制 =====
        /// <summary>当前场景已持续的tick数</summary>
        public int ScenarioTick { get; set; } = 0;

        /// <summary>当前场景总tick数</summary>
        public int ScenarioDuration { get; set; } = 10;

        // ===== 内部辅助 =====
        /// <summary>数据变化间隔（秒）</summary>
        public int DataChangeInterval { get; set; } = 10;

        // ===== 统计信息 =====
        /// <summary>本次启动后累计总加工零件数</summary>
        public int TotalPartsSinceStart { get; set; } = 0;

        /// <summary>按NC程序名统计的零件数（程序名 → 零件数）</summary>
        public Dictionary<string, int> PartsByProgram { get; set; } = new Dictionary<string, int>();

        // ===== 事件历史 =====
        /// <summary>事件变更历史记录（最多保留1000条）</summary>
        public List<EventRecord> EventHistory { get; set; } = new List<EventRecord>();

        /// <summary>记录一次事件</summary>
        public void RecordEvent(string eventType, string oldProgram, string newProgram, int partCountBefore, int partCountAfter, string detail = null)
        {
            var record = new EventRecord
            {
                Timestamp = DateTime.Now,
                DeviceCode = DeviceCode,
                EventType = eventType,
                OldProgram = oldProgram ?? "",
                NewProgram = newProgram ?? "",
                PartCountBefore = partCountBefore,
                PartCountAfter = partCountAfter,
                Detail = detail ?? ""
            };
            EventHistory.Add(record);
            // 限制历史记录数量
            if (EventHistory.Count > 1000) EventHistory.RemoveAt(0);
        }
    }

    /// <summary>设备事件记录</summary>
    public class EventRecord
    {
        /// <summary>事件时间</summary>
        public DateTime Timestamp { get; set; }
        /// <summary>设备编码</summary>
        public string DeviceCode { get; set; }
        /// <summary>事件类型: program_change, manual_reset, power_off, power_on, scenario_change</summary>
        public string EventType { get; set; }
        /// <summary>变更前程序名</summary>
        public string OldProgram { get; set; }
        /// <summary>变更后程序名</summary>
        public string NewProgram { get; set; }
        /// <summary>变更前零件数</summary>
        public int PartCountBefore { get; set; }
        /// <summary>变更后零件数</summary>
        public int PartCountAfter { get; set; }
        /// <summary>额外详情</summary>
        public string Detail { get; set; }
    }
}
