#nullable enable
using System;
using System.Collections.Generic;

namespace IGP.UnitySDK.Models
{
    /// <summary>
    /// Desktop session 登录用户上下文
    /// </summary>
    [Serializable]
    public class IGPDesktopUserContext
    {
        public string userId = string.Empty;
        public string accountId = string.Empty;
        public string loginState = string.Empty;
    }

    /// <summary>
    /// Desktop session 能力集合
    /// </summary>
    [Serializable]
    public class IGPDesktopCapabilitySet
    {
        private readonly HashSet<int> enabledCapabilityFields = new HashSet<int>();

        public bool achievements;
        public bool userContext;
        public bool gameAuthorization;
        public bool antiAddiction;
        public bool lyingBottle;
        public bool cloudArchive;
        public bool leaderboard;
        public bool share;

        public bool SupportsCapability(int fieldNumber)
        {
            switch (fieldNumber)
            {
                case 1: return achievements;
                case 3: return userContext;
                case 5: return gameAuthorization;
                case 6: return antiAddiction;
                case 7: return lyingBottle;
                case 8: return cloudArchive;
                case 9: return leaderboard;
                case 10: return share;
                default: return enabledCapabilityFields.Contains(fieldNumber);
            }
        }

        internal void SetCapability(int fieldNumber, bool enabled)
        {
            switch (fieldNumber)
            {
                case 1: achievements = enabled; break;
                case 3: userContext = enabled; break;
                case 5: gameAuthorization = enabled; break;
                case 6: antiAddiction = enabled; break;
                case 7: lyingBottle = enabled; break;
                case 8: cloudArchive = enabled; break;
                case 9: leaderboard = enabled; break;
                case 10: share = enabled; break;
                default:
                    if (enabled)
                    {
                        enabledCapabilityFields.Add(fieldNumber);
                    }
                    else
                    {
                        enabledCapabilityFields.Remove(fieldNumber);
                    }
                    break;
            }
        }

        internal IEnumerable<int> GetEnabledCapabilityFields()
        {
            for (var fieldNumber = 1; fieldNumber <= 10; fieldNumber++)
            {
                if (SupportsCapability(fieldNumber))
                {
                    yield return fieldNumber;
                }
            }

            foreach (var fieldNumber in enabledCapabilityFields)
            {
                if (fieldNumber < 1 || fieldNumber > 10)
                {
                    yield return fieldNumber;
                }
            }
        }
    }

    /// <summary>
    /// Desktop session 当前登录用户资料
    /// </summary>
    [Serializable]
    public class IGPDesktopUserProfile
    {
        public string nickname = string.Empty;
        public string displayTag = string.Empty;
        public bool avatarAvailable;
        public string avatarVersion = string.Empty;
    }

    /// <summary>
    /// Desktop session 用户头像元信息
    /// </summary>
    [Serializable]
    public class IGPDesktopUserAvatarInfo
    {
        public bool available;
        public string contentType = string.Empty;
        public int width;
        public int height;
        public int encodedByteLength;
        public int decodedByteLength;
        public string avatarVersion = string.Empty;
    }

    /// <summary>
    /// Desktop session 用户头像 PNG 数据
    /// </summary>
    [Serializable]
    public class IGPDesktopUserAvatarImage
    {
        public IGPDesktopUserAvatarInfo info = new IGPDesktopUserAvatarInfo();
        public byte[] pngBytes = Array.Empty<byte>();
    }

    /// <summary>
    /// Desktop session 请求的授权验证结果
    /// </summary>
    [Serializable]
    public class IGPDesktopAuthorizationRequestResult
    {
        public bool authorizationRequired = true;
        public bool offlineMode;
        public string pipeName = string.Empty;
    }

    /// <summary>
    /// Desktop session notification for directly launching an offline workshop map.
    /// </summary>
    [Serializable]
    public class IGPDesktopOfflineMapLaunchRequestedEvent
    {
        public int appId;
        public string mapPublicId = string.Empty;
        public int versionId;
        public string mapPath = string.Empty;
        public string? title;
        public string? version;
    }

    /// <summary>
    /// 游戏内 IGP 账号登录与实名认证 WebView 入口
    /// </summary>
    [Serializable]
    public class IGPAntiAddictionRealNameWebSession
    {
        public string ticket = string.Empty;
        public string url = string.Empty;
        public string expiresAt = string.Empty;
    }

    [Serializable]
    public enum IGPAntiAddictionState
    {
        Disabled = 0,
        Allowed = 1,
        Blocked = 2,
        PendingRealName = 3,
        Verifying = 4,
        Failed = 5,
    }

    [Serializable]
    public enum IGPAgeBand
    {
        Unknown = 0,
        Under8 = 1,
        Age8To15 = 2,
        Age16To17 = 3,
        Adult = 4,
    }

    [Serializable]
    public class IGPAntiAddictionStatus
    {
        public bool enabled;
        public bool canPlayNow;
        public string state = nameof(IGPAntiAddictionState.Disabled);
        public string reasonCode = string.Empty;
        public string reasonMessage = string.Empty;
        public bool? isMinor;
        public string ageBand = nameof(IGPAgeBand.Unknown);
        public string evaluatedAt = string.Empty;
        public string playableUntil = string.Empty;
        public string nextPlayableAt = string.Empty;
        public string nextStatusChangeAt = string.Empty;

        public IGPAntiAddictionState ParsedState
        {
            get
            {
                return Enum.TryParse(state, true, out IGPAntiAddictionState parsed)
                    ? parsed
                    : IGPAntiAddictionState.Disabled;
            }
        }

        public IGPAgeBand ParsedAgeBand
        {
            get
            {
                return Enum.TryParse(ageBand, true, out IGPAgeBand parsed)
                    ? parsed
                    : IGPAgeBand.Unknown;
            }
        }
    }
}
