using System;
using StandardScene.Signal.Model;

namespace StandardScene.Signal.Logic
{
    /// <summary>
    /// 一条握手点配置的解析结果。新列（机构/工位/动作/附加参数）优先，旧 SignalParams 作回退。
    /// </summary>
    public sealed class SignalStopSpec
    {
        public string SignalType { get; init; } = "";

        public string SignalParams { get; init; } = "";

        public string[] Parts { get; init; } = Array.Empty<string>();

        public string JgName { get; init; } = "";

        public string DockId { get; init; } = "";

        public string Action { get; init; } = "";

        public string ExtraParams { get; init; } = "";

        public string Part(int index)
        {
            if (index < 0 || index >= Parts.Length)
                return "";
            return Parts[index] ?? "";
        }

        public static SignalStopSpec Parse(string signalType, string signalParams)
        {
            var type = (signalType ?? "").Trim();
            var raw = signalParams ?? "";
            var parsed = new SignalStopSpec
            {
                SignalType = type,
                SignalParams = raw,
                Parts = raw.Split(new[] { ';' }, StringSplitOptions.None)
            };
            return EnrichFromParts(parsed);
        }

        public static SignalStopSpec From(HandshakePointModel model)
        {
            if (model == null)
                return null;

            var type = (model.SignalType ?? "").Trim();
            if (string.Equals(type, "TimedCharging", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(type, "RateFlowControl", StringComparison.OrdinalIgnoreCase))
            {
                var raw = First(model.ExtraParams, model.SignalParams);
                return Parse(type, raw);
            }

            var parsed = Parse(type, model.SignalParams ?? "");
            var jg = First(model.JgName, parsed.JgName);
            var action = First(model.Action, parsed.Action);
            var dock = First(model.DockId, parsed.DockId);
            var extra = First(model.ExtraParams, parsed.ExtraParams);
            return new SignalStopSpec
            {
                SignalType = parsed.SignalType,
                SignalParams = parsed.SignalParams,
                Parts = parsed.Parts,
                JgName = jg,
                DockId = dock,
                Action = action,
                ExtraParams = extra
            };
        }

        public bool Is(string type) =>
            string.Equals(SignalType, type, StringComparison.OrdinalIgnoreCase);

        private static SignalStopSpec EnrichFromParts(SignalStopSpec parsed)
        {
            var type = parsed.SignalType;
            if (string.Equals(type, "TimedCharging", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(type, "RateFlowControl", StringComparison.OrdinalIgnoreCase))
            {
                return new SignalStopSpec
                {
                    SignalType = parsed.SignalType,
                    SignalParams = parsed.SignalParams,
                    Parts = parsed.Parts,
                    ExtraParams = parsed.SignalParams
                };
            }

            var point = string.Equals(type, "PointControl", StringComparison.OrdinalIgnoreCase);
            var jg = point ? parsed.Part(1).Trim() : parsed.Part(0).Trim();
            var action = point ? parsed.Part(0).Trim() : parsed.Part(1).Trim();
            var dock = "";
            var extra = "";
            var p2 = parsed.Part(2).Trim();
            if (LooksLikeDock(p2))
                dock = p2;
            else if (LooksLikeRateFlow(p2))
                extra = p2;
            if (string.IsNullOrEmpty(extra))
                extra = parsed.Part(3).Trim();
            return new SignalStopSpec
            {
                SignalType = parsed.SignalType,
                SignalParams = parsed.SignalParams,
                Parts = parsed.Parts,
                JgName = jg,
                DockId = dock,
                Action = action,
                ExtraParams = extra
            };
        }

        private static string First(string a, string b)
        {
            if (!string.IsNullOrWhiteSpace(a))
                return a.Trim();
            return (b ?? "").Trim();
        }

        private static bool LooksLikeRateFlow(string s) =>
            !string.IsNullOrEmpty(s) && s.IndexOf('-') >= 0;

        private static bool LooksLikeDock(string s) =>
            !string.IsNullOrEmpty(s) && s.IndexOf('-') < 0 && s.IndexOf(',') < 0;
    }
}
