<?php
namespace Mainto\RpcServer\RpcServer\ContextTrait;

use Mainto\RpcServer\RpcUtil\RpcMessageQueue;
use Mainto\RpcServer\Protocol\Common\Types\RequestHeaderType;

trait RpcMessageTrait {
    use RequestTrait;
    use HeaderTrait;

    /**
     * @return bool
     */
    public function isRpcMessageHookRequest () {
        return in_array($this->request->getType(), [
            RequestHeaderType::MessageNormalType,
            RequestHeaderType::MessageRetryType,
            RequestHeaderType::MessageDelayType,
            RequestHeaderType::WebsocketNormalType,
            RequestHeaderType::WebsocketConnectType,
            RequestHeaderType::WebsocketDisconnectType,
        ]);
    }

    /**
     * @return bool
     */
    public function isRpcWebsocketRequest () {
        return in_array($this->request->getType(), [
            RequestHeaderType::WebsocketNormalType,
            RequestHeaderType::WebsocketConnectType,
            RequestHeaderType::WebsocketDisconnectType,
        ]);
    }

    /**
     * 获得消息队列名称
     *
     * @return null|string
     */
    public function getRpcMessageHookName (): ?string {
        if ($this->isRpcMessageHookRequest()) {
            return $this->getHeader("message-name");
        }

        return null;
    }

    /**
     * 是否是重试的Message
     *
     * @return bool|null
     */
    public function isRetry (): ?bool {
        if ($this->isRpcMessageHookRequest()) {
            return $this->request->getType() == RequestHeaderType::MessageRetryType;
        }

        return null;
    }

    /**
     * 是否是延迟的Block
     *
     * @return bool|null
     */
    public function isDelay (): ?bool {
        if ($this->isRpcMessageHookRequest()) {
            return $this->request->getType() == RequestHeaderType::MessageDelayType;
        }

        return null;
    }

    /**
     * 获得延迟时间
     *
     * @return int|null
     */
    public function getDelayTime (): ?int {
        if ($this->isRpcMessageHookRequest()) {
            return $this->getHeader("delay");
        }

        return null;
    }

    /**
     * 获得消息类型（如果存在）
     *
     * @return string|null
     */
    public function getMsgType (): ?string {
        if ($this->isRpcWebsocketRequest()) {
            return $this->request->getType() == RequestHeaderType::WebsocketNormalType ? 'message' : 'control';
        }

        return null;
    }

    /**
     * 回复用户消息
     *
     * @param $msg
     * @return bool
     */
    public function replayMessage (string $msg): bool {
        if ($this->isRpcMessageHookRequest()) {
            $roomName = $this->getRoomName();
            $userId = $this->getUserId();
            if ($roomName && $userId) {
                RpcMessageQueue::getInstance()->addMessageToWebSocket($roomName, $userId, $msg);
                return true;
            }
        }

        return false;
    }

    /**
     * 获得房间名称（如果存在）
     *
     * @return string|null
     */
    public function getRoomName (): ?string {
        if ($this->isRpcMessageHookRequest()) {
            return $this->getHeader("roomName");
        }

        return null;
    }

    /**
     * 获得用户ID（如果存在）
     *
     * @return string|null
     */
    public function getUserId (): ?string {
        if ($this->isRpcMessageHookRequest()) {
            return $this->getHeader("userId");
        }

        return null;
    }

    /**
     * 回复用户消息
     *
     * @param $userId
     * @param $msg
     * @return bool
     */
    public function sendMessage (string $userId, string $msg): bool {
        if ($this->isRpcMessageHookRequest()) {
            $roomName = $this->getRoomName();
            if ($roomName && $userId) {
                RpcMessageQueue::getInstance()->addMessageToWebSocket($roomName, $userId, $msg);
                return true;
            }
        }
        return false;
    }

    /**
     * 发送用户消息
     *
     * @param string $roomName
     * @param string $userId
     * @param string $msg
     */
    public function sendMessageToUser (string $roomName, string $userId, string $msg) {
        RpcMessageQueue::getInstance()->addMessageToWebSocket($roomName, $userId, $msg);
    }

    /**
     * 发送消息给自己
     *
     * @param string $msg
     * @return bool
     */
    public function sendMessageToSelf (string $msg): bool {
        if ($this->isRpcMessageHookRequest()) {
            $roomName = $this->getRoomName();
            $userId = $this->getUserId();
            if ($roomName && $userId) {
                RpcMessageQueue::getInstance()->addMessageToWebSocket($roomName, $userId, $msg);
                return true;
            }
        }
        return false;
    }

    /**
     * 广播房间消息
     *
     * @param $msg
     * @return bool
     */
    public function broadcastMessage (string $msg): bool {
        if ($this->isRpcMessageHookRequest()) {
            $roomName = $this->getRoomName();
            if ($roomName) {
                RpcMessageQueue::getInstance()->addMessageToWebSocket($roomName, "[all]", $msg);
                return true;
            }
        }
        return false;
    }

    /**
     * 广播消息到指定房间
     *
     * @param string $roomName
     * @param string $msg
     */
    public function broadcastMessageToRoom (string $roomName, string $msg) {
        RpcMessageQueue::getInstance()->addMessageToWebSocket($roomName, "[all]", $msg);
    }

    /**
     * 获得内容类型
     * @return null|string
     */
    public function getContextType (): ?string {
        if ($this->isRpcMessageHookRequest()) {
            // todo getContextType
        }

        return null;
    }
}