using Simple3.RCS;
using SimpleCore.PropType;
using StandardScene.CarTypes;
using System;
using System.Globalization;
using Simple3.RCS.CarTypes;

namespace StandardScene.Scheduler.FassEvent
{
    /// <summary>
    /// 将 StandardScene 车辆对象转换为 FASS 事件系统可识别的快照字段。
    /// 负责编号、地标、状态、电量等与 <c>EventCarService.TriggerHandler</c> 对齐的映射。
    /// </summary>
    internal static class FassEventCarSnapshotFactory
    {
        /// <summary>
        /// 获取车辆“下一地标”编码。
        /// 优先级：status.enums["NextNode"] → tags["NextNode"] → pendingLocks 首站（TagValue 或站点 ID）。
        /// </summary>
        public static string GetNextNodeCode(Car car)
        {
            if (car.status?.enums != null && car.status.enums.TryGetValue("NextNode", out var node) && !string.IsNullOrWhiteSpace(node))
            {
                return node;
            }

            if (car.tags != null && car.tags.TryGetValue("NextNode", out var tagNode) && !string.IsNullOrWhiteSpace(tagNode))
            {
                return tagNode;
            }

            // 调度 pendingLocks 通常表示车辆即将前往的站点，可近似为 FASS NextNodeCode。
            if (car.status?.pendingLocks != null && car.status.pendingLocks.Length > 0)
            {
                var pendingSiteId = car.status.pendingLocks[0];
                var site = SimpleCore.SimpleLib.GetSite(pendingSiteId);
                if (site?.fields != null && site.fields.TryGetValue("TagValue", out var tagValue) && !string.IsNullOrWhiteSpace(tagValue))
                {
                    return tagValue;
                }

                return pendingSiteId.ToString(CultureInfo.InvariantCulture);
            }

            return string.Empty;
        }

        /// <summary>
        /// 根据车辆与上一周期地标构建完整快照。
        /// </summary>
        /// <param name="car">场景车辆。</param>
        /// <param name="prevNodeCode">上一周期 CurrentNode，由 EventCarMission 维护。</param>
        /// <param name="nextNodeCode">下一地标；为空时自动调用 <see cref="GetNextNodeCode"/>。</param>
        public static FassEventCarSnapshot Create(Car car, string prevNodeCode, string nextNodeCode)
        {
            return new FassEventCarSnapshot
            {
                CarId = car.id,
                Code = GetCarCode(car),
                CarModel = GetCarModel(car),
                PrevNodeCode = prevNodeCode,
                CurrentNodeCode = GetCurrentNodeCode(car),
                NextNodeCode = string.IsNullOrWhiteSpace(nextNodeCode) ? GetNextNodeCode(car) : nextNodeCode,
                State = GetFassState(car),
                Angle = (int)Math.Round(car.th),
                Charge = GetCharge(car)
            };
        }

        /// <summary>
        /// 获取 FASS 车辆编号。MagCar 优先使用 VehicleCode，否则 fields["Code"]，最后回退 name。
        /// </summary>
        public static string GetCarCode(Car car)
        {
            if (car is MagCar magCar && magCar.VehicleCode > 0)
            {
                return magCar.VehicleCode.ToString(CultureInfo.InvariantCulture);
            }

            if (car.fields != null && car.fields.TryGetValue("Code", out var code) && !string.IsNullOrWhiteSpace(code))
            {
                return code;
            }

            return car.name;
        }

        /// <summary>获取车型。下料站 InplaceStaion 根据 CarModel 在 ME11 / 放行车型间切换。</summary>
        public static string GetCarModel(Car car)
        {
            if (car.fields != null && car.fields.TryGetValue("CarModel", out var model) && !string.IsNullOrWhiteSpace(model))
            {
                return model;
            }

            return car.GetType().Name;
        }

        /// <summary>
        /// 获取当前地标号。MagCar 上报后写入 status.enums["CurrentNode"]；
        /// 其他车型可回退到 siteID。
        /// </summary>
        public static string GetCurrentNodeCode(Car car)
        {
            if (car.status?.enums != null && car.status.enums.TryGetValue("CurrentNode", out var node) && !string.IsNullOrWhiteSpace(node))
            {
                return node;
            }

            return car.siteID > 0 ? car.siteID.ToString(CultureInfo.InvariantCulture) : string.Empty;
        }

        /// <summary>
        /// 将 StandardScene 车辆状态映射为 FASS 英文字符串。
        /// <para>
        /// 可手动覆盖：tags["FassState"] 或 enums["FassState"]。
        /// WaitPass 需在停止中且 tags 含 WaitPass（FASS 中“等待放行”态）。
        /// </para>
        /// </summary>
        public static string GetFassState(Car car)
        {
            if (car.tags != null && car.tags.TryGetValue("FassState", out var tagState) && !string.IsNullOrWhiteSpace(tagState))
            {
                return tagState;
            }

            if (car.status?.enums != null && car.status.enums.TryGetValue("FassState", out var enumState) && !string.IsNullOrWhiteSpace(enumState))
            {
                return enumState;
            }

            if (car.status?.enums != null && car.status.enums.TryGetValue("State", out var state))
            {
                switch (state)
                {
                    case "运行中":
                        return "Running";
                    case "停止中":
                        return car.tags != null && car.tags.ContainsKey("WaitPass") ? "WaitPass" : "Stopping";
                    case "未准备":
                        return "NotReady";
                    case "充电中":
                        return "Charging";
                    default:
                        return state;
                }
            }

            return string.Empty;
        }

        /// <summary>从 status.enums["Soc"] 解析电量百分比。</summary>
        private static double GetCharge(Car car)
        {
            if (car.status?.enums != null &&
                car.status.enums.TryGetValue("Soc", out var soc) &&
                double.TryParse(soc, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
            {
                return value;
            }

            return 0;
        }
    }
}
