#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>
        /// 创建 RPC 注册消息
        /// </summary>
        public static Message CreateRPCRegister(string roomId, string playerId, string name)
        {
            return new Message
            {
                type = "rpc_register",
                roomId = roomId,
                playerId = playerId,
                content = new RPCRegisterContent { name = name },
                reliable = true,
            };
        }

        /// <summary>
        /// 创建 RPC 取消注册消息
        /// </summary>
        public static Message CreateRPCUnregister(string roomId, string playerId, string name)
        {
            return new Message
            {
                type = "rpc_unregister",
                roomId = roomId,
                playerId = playerId,
                content = new RPCUnregisterContent { name = name },
                reliable = true,
            };
        }

        /// <summary>
        /// 创建 RPC 调用消息
        /// </summary>
        public static Message CreateRPCCall(string roomId, string playerId, string name, object? data = null, string mode = "all", string? requestId = null)
        {
            return new Message
            {
                type = "rpc_call",
                roomId = roomId,
                playerId = playerId,
                content = new RPCCallContent
                {
                    name = name,
                    data = data,
                    mode = mode,
                    requestId = requestId ?? string.Empty,
                },
                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,
            };
        }

        /// <summary>
        /// 创建 RPC 响应消息（由服务器发送给调用者）
        /// </summary>
        public static Message CreateRPCResponse(string roomId, string playerId, string requestId, string name, object? data, string? error = null)
        {
            return new Message
            {
                type = "rpc_response",
                roomId = roomId,
                playerId = playerId,
                content = new {
                    requestId = requestId,
                    name = name,
                    data = data,
                    error = error
                },
                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>();
    }

    [Serializable]
    public class RPCRegisterContent
    {
        public string name = string.Empty;
    }

    [Serializable]
    public class RPCUnregisterContent
    {
        public string name = string.Empty;
    }

    [Serializable]
    public class RPCCallContent
    {
        public string name = string.Empty;
        public object? data;
        public string mode = "all";
        public string requestId = string.Empty;
    }
}
