#nullable enable
using System;
using UnityEngine;

namespace IGP.UnitySDK.Models
{
    /// <summary>
    /// WebSocket 消息模型
    /// </summary>
    [Serializable]
    public class Message
    {
        public string type = string.Empty;
        public string roomId = string.Empty;
        public string playerId = string.Empty;
        public string targetPlayerId = string.Empty;
        public object? content;
        public bool reliable = true;
        public string timestamp = string.Empty; // Go time.Time parses to string in JSON

        /// <summary>
        /// 创建心跳消息
        /// </summary>
        public static Message CreatePing(string roomId, string playerId)
        {
            return new Message
            {
                type = "ping",
                roomId = roomId,
                playerId = playerId,
                reliable = true
            };
        }

        /// <summary>
        /// 创建状态设置消息
        /// </summary>
        public static Message CreateStateSet(string roomId, string playerId, string scope, string key, object? value, string? targetPlayerId = null, bool reliable = true)
        {
            return new Message
            {
                type = "state_set",
                roomId = roomId,
                playerId = playerId,
                content = new StateSetContent
                {
                    scope = scope,
                    key = key,
                    value = value,
                    playerId = targetPlayerId ?? string.Empty,
                    reliable = reliable,
                },
                reliable = reliable,
            };
        }

        /// <summary>
        /// 创建状态获取消息（服务端会广播 type=state_get 的响应）
        /// </summary>
        public static Message CreateStateGet(string roomId, string playerId, string scope, string key, string? targetPlayerId = null)
        {
            return new Message
            {
                type = "state_get",
                roomId = roomId,
                playerId = playerId,
                content = new StateGetContent
                {
                    scope = scope,
                    key = key,
                    playerId = targetPlayerId ?? string.Empty
                },
                reliable = true,
            };
        }

        /// <summary>
        /// 创建状态重置消息（scope=global/player）。keysToExclude 可选。
        /// </summary>
        public static Message CreateStateReset(string roomId, string playerId, string scope, string[]? keysToExclude = null)
        {
            return new Message
            {
                type = "state_reset",
                roomId = roomId,
                playerId = playerId,
                content = new StateResetContent
                {
                    scope = scope,
                    keysToExclude = keysToExclude ?? Array.Empty<string>(),
                },
                reliable = true,
            };
        }

        /// <summary>
        /// 创建队伍变更消息
        /// </summary>
        public static Message CreateTeamChange(string roomId, string playerId, string teamId)
        {
            return new Message
            {
                type = "team_change",
                roomId = roomId,
                playerId = playerId,
                content = new { playerId = playerId, teamId = teamId },
                reliable = true,
            };
        }

        /// <summary>
        /// 创建队伍初始化消息
        /// </summary>
        public static Message CreateTeamInitialize(string roomId, string playerId, Team[] teams)
        {
            return new Message
            {
                type = "team_initialize",
                roomId = roomId,
                playerId = playerId,
                content = new { teams = teams },
                reliable = true,
            };
        }

        /// <summary>
        /// 创建队伍状态更新消息
        /// </summary>
        public static Message CreateTeamStatus(string roomId, string playerId, object status)
        {
            return new Message
            {
                type = "team_status",
                roomId = roomId,
                playerId = playerId,
                content = status,
                reliable = true,
            };
        }

    }

    [Serializable]
    public class StateSetContent
    {
        public string scope = string.Empty;
        public string key = string.Empty;
        public object? value;
        public string playerId = string.Empty;
        public bool reliable;
    }

    [Serializable]
    public class StateGetContent
    {
        public string scope = string.Empty;
        public string key = string.Empty;
        public string playerId = string.Empty;
    }

    [Serializable]
    public class StateResetContent
    {
        public string scope = string.Empty;
        public string[] keysToExclude = Array.Empty<string>();
    }

}
