using System;
using System.Collections.Generic;

namespace AnotherReplayReader
{
    enum FactionKind
    {
        Player,
        Observer,
        Unknown
    }

    internal sealed class Mod : IComparable
    {
        public readonly string ModName;
        public readonly string ModVersion;
        public bool IsRA3 => ModName.Equals("RA3");

        public Mod(string modInfo)
        {
            var splitted = modInfo.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
            ModName = splitted[0];
            ModVersion = string.Empty;
            if (IsRA3)
            {
                return;
            }
            ModVersion = splitted[1];
        }

        public override string ToString()
        {
            if (IsRA3)
            {
                return "原版";
            }
            return ModName + ' ' + ModVersion;
        }

        public int CompareTo(object other)
        {
            if (!(other is Mod))
            {
                return GetType().FullName.CompareTo(other.GetType().FullName);
            }

            var otherMod = (Mod)other;
            if (IsRA3 != otherMod.IsRA3)
            {
                if (IsRA3)
                {
                    return 1;
                }
                else
                {
                    return -1;
                }
            }

            var modCompare = ModName.CompareTo(otherMod.ModName);
            if (modCompare != 0)
            {
                return modCompare;
            }

            return ModVersion.CompareTo(otherMod.ModVersion);
        }
    }

    internal sealed class Faction
    {
        public readonly FactionKind Kind;
        public readonly string Name;

        public Faction(FactionKind kind, string name)
        {
            Kind = kind;
            Name = name;
        }
    }

    internal static class ModData
    {
        private static readonly Faction _unknown = new(FactionKind.Unknown, "未知阵营");
        private static readonly IReadOnlyDictionary<string, IReadOnlyDictionary<int, Faction>> _factions;


        static ModData()
        {
            var ra3Factions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "盟军") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
            };
            var arFactions = new Dictionary<int, Faction>
            {
                { 1, new Faction(FactionKind.Player, "阳炎") },
                { 2, new Faction(FactionKind.Player, "天琼") },
                { 3, new Faction(FactionKind.Player, "OB") },
                { 4, new Faction(FactionKind.Player, "帝国") },
                { 5, new Faction(FactionKind.Player, "鹰眼") },
                { 6, new Faction(FactionKind.Player, "解说员") },
                { 7, new Faction(FactionKind.Player, "盟军") },
                { 8, new Faction(FactionKind.Player, "克格勃") },
                { 11, new Faction(FactionKind.Player, "血月") },
                { 12, new Faction(FactionKind.Player, "随机") },
                { 13, new Faction(FactionKind.Player, "苏联") },
                { 14, new Faction(FactionKind.Player, "涅墨西斯") },
                { 0, new Faction(FactionKind.Player, "AI") },
            };
            var coronaFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "盟军") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
                { 9, new Faction(FactionKind.Player, "神州") },
             };
            var dawnFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "禁卫军") },
                { 5, new Faction(FactionKind.Player, "盟军") },
                { 9, new Faction(FactionKind.Player, "革命军") },
                { 10, new Faction(FactionKind.Player, "德法同盟") },
                { 11, new Faction(FactionKind.Player, "随机") },
                { 12, new Faction(FactionKind.Player, "苏联") },
             };
            var insFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "盟军") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
            };
            var fsFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "盟军") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
            };
            var eisenreichFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "德国") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
            };
            var tnwFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "帝国") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "盟军") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
            };
            var wopFactions = new Dictionary<int, Faction>
            {
                { 0, new Faction(FactionKind.Player, "AI") },
                { 1, new Faction(FactionKind.Observer, "观察员") },
                { 2, new Faction(FactionKind.Player, "日本") },
                { 3, new Faction(FactionKind.Observer, "解说员") },
                { 4, new Faction(FactionKind.Player, "美国") },
                { 7, new Faction(FactionKind.Player, "随机") },
                { 8, new Faction(FactionKind.Player, "苏联") },
            };
            _factions = new Dictionary<string, IReadOnlyDictionary<int, Faction>>(StringComparer.CurrentCultureIgnoreCase)
            {
                ["RA3"] = ra3Factions,
                ["Armor Rush"] = arFactions,
                ["ART"] = arFactions,
                ["corona"] = coronaFactions,
                ["Dawn"] = dawnFactions,
                ["Insurrection"] = insFactions,
                ["1.12+FS"] = fsFactions,
                ["Eisenreich"] = eisenreichFactions,
                ["The New World"] = tnwFactions,
                ["War Of Powers"] = wopFactions
            };
        }

        public static Faction GetFaction(Mod mod, int factionId)
        {
            if (_factions.TryGetValue(mod.ModName, out var table))
            {
                if (table.TryGetValue(factionId, out var result))
                {
                    return result;
                }
            }
            return _unknown;
        }
    }

}