<?php
/**
 * Created by PhpStorm.
 * User: gevnc
 * Date: 2018/5/16
 * Time: 17:49
 */

namespace App\Services;

use App\Models\PkRoom;
use App\Traits\Singleton;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class PkService
{
    use Singleton;
    const QUESTION_COLLECT = "bs_question_collect";
    const PK_ROOMS = "bs_pk_rooms";
    const PK_ROOM_ANSWERS = "bs_pk_room_answers";
    const PK_QUEUE = "bs_pk_queue";
    const PK_STATUS_QUEUE = "bs_pk_room_queue";
    const PK_ROOM_JOINS = "bs_pk_room_joins";
    const PK_RUN = "bs_pk_room_run";
    const NOT_COMPLETE_PKS = "bs_pk_room_not_completes";
    const QUESTION_COUNT = 5;
    const COUNT_DOWN = 13;
    const ROOM_OVER_TIME = 300;
    /**
     * 获取房间信息
     * @param $roomId
     * @return array
     */
    public function getRoomInfo($roomId)
    {
        return Redis::hGetAll(self::PK_ROOMS . ":" . $roomId);
    }

    /**
     * 获取PK对战的双方信息
     * @param $sponsorUserId
     * @param $challengerUserId
     * @return array
     */
    public function getPkUserInfo($sponsorUserId, $challengerUserId)
    {
        $data = [
            "sponsor_user_id" => $sponsorUserId,
            "sponsor_name" => "",
            "sponsor_short_name" => "",
            "sponsor_headpic_url" => "",
            "sponsor_department" => "",
            "challenger_user_id" => $challengerUserId,
            "challenger_name" => "",
            "challenger_short_name" => "",
            "challenger_headpic_url" => "",
            "challenger_department" => ""
        ];
        if ($sponsorUserId) {
            $sponsor = UserService::getInstance()->getUser($sponsorUserId);
            if ($sponsor) {
                $data["sponsor_name"] = $sponsor["name"];
                $data["sponsor_short_name"] = mb_substr($sponsor["name"], -2, 2, "utf-8");
                $data["sponsor_headpic_url"] = $sponsor["avatar"];
                $data["sponsor_department"] = DepartmentService::getInstance()->getDepartmentName($sponsor["department_id"]);
            }
        }
        if ($challengerUserId) {
            $challenger = UserService::getInstance()->getUser($challengerUserId);
            if ($challenger) {
                $data["challenger_name"] = $challenger["name"];
                $data["challenger_short_name"] = mb_substr($challenger["name"], -2, 2, "utf-8");
                $data["challenger_headpic_url"] = $challenger["avatar"];
                $data["challenger_department"] = DepartmentService::getInstance()->getDepartmentName($challenger["department_id"]);
            }
        }
        return $data;
    }

    /**
     * 开始PK
     * @param $activityId
     * @param $sponsorUserId
     * @param $challengerUserId
     * @return mixed
     */
    public function startPk($activityId,$sponsorUserId, $challengerUserId){

        try{

            //如果发起人已经在PK则，返回null
            if(UserService::getInstance()->getUserCurrentWork($sponsorUserId)){
                return null;
            }

            $brainstorming = BrainstormingService::getInstance()->get($activityId);
            $corpId = $brainstorming["corp_id"];

            $count = $brainstorming["pk_question_num"];

            $questionIds = Redis::sRandMember(self::QUESTION_COLLECT.":".$activityId.":pk", $count);
            $data = [
                "corp_id" => $corpId,
                "activity_id" => $activityId,
                "sponsor_user_id" => $sponsorUserId,
                "challenger_user_id" => $challengerUserId,
                "start_time" => time(),
                "knowledge_money" => 0,
                "question_ids" => implode(",", $questionIds),
                "win_user_id" => 0,
                "status" => 3,
                "is_success" => 0
            ];

            $pkRoomModel = PkRoom::create($data);
            if (!empty($pkRoomModel)) {
                $roomId = $pkRoomModel->room_id;
                $data["create_time"] = time();
                $data["room_id"] = $roomId;
                $data["fd"] = 0;
                $data["question_count"] = $count;
                $data["step"] = 0;
                $data["sponsor_score"] = 0;
                $data["challenger_score"] = 0;
                Redis::hMset(self::PK_ROOMS . ":" . $roomId, $data);
                Redis::expire(self::PK_ROOMS . ":" . $roomId,86400);
                Redis::sAdd(self::PK_RUN, $roomId);

                $questions = QuestionService::getInstance()->mget($questionIds);
                $step = 1;
                //生成答题
                foreach ($questions as $question) {
                    $this->addAnswer($roomId, $question, $step, $count, $sponsorUserId);
                    $this->addAnswer($roomId, $question, $step, $count, $challengerUserId);
                    $step++;
                }

                //发送PK开始通知
                $pkUserInfo = $this->getPkUserInfo($sponsorUserId, $challengerUserId);
                $responseData = [
                    "room_id" => $roomId,
                    "knowledge_money" => 0,
                    "status" => 3,
                    "create_time" => time()
                ];
                $responseData = array_merge($responseData, $pkUserInfo);


                PushMessageService::getInstance()->pushByUserId("pk", "startNotify", $responseData, $sponsorUserId,0);
                PushMessageService::getInstance()->pushByUserId("pk", "startNotify", $responseData, $challengerUserId,0);
                //设置用户正在PK
                UserService::getInstance()->setUserCurrentWork($sponsorUserId,'pk',$roomId,20);
                UserService::getInstance()->setUserCurrentWork($challengerUserId,'pk',$roomId,20);


                //延时3秒发送开始答题
                Redis::hSet(self::PK_ROOMS . ":" . $roomId, "step", 1);
                //处理发起人
                Redis::hSet(self::PK_ROOM_ANSWERS . ":" . $roomId . ":" . $sponsorUserId . ":1" , "answer_start_time", time());
                $this->addAnswerQueue($roomId, 1, $sponsorUserId);
                //处理挑战人
                Redis::hSet(self::PK_ROOM_ANSWERS . ":" . $roomId . ":" . $challengerUserId . ":1", "answer_start_time", time());
                $this->addAnswerQueue($roomId, 1, $challengerUserId);

                $this->sendQuestion($roomId,1,$sponsorUserId,3);
                $this->sendQuestion($roomId,1,$challengerUserId,3);

                return $roomId;
            }
        }catch (\Exception $exception){
            Log::info($exception->getTraceAsString());
            return null;
        }

    }


    /**
     * 获取某闯关的第几到题目
     * @param $roomId
     * @param $step
     * @param $userId
     * @return mixed
     */
    public function getQuestion($roomId, $step, $userId)
    {
        $userAnswer = $this->getUserAnswer($roomId, $step, $userId);
        if ($userAnswer) {
            $question = QuestionService::getInstance()->get($userAnswer["question_id"]);
            return [
                "room_id" => $roomId,
                "count" => $userAnswer["count"],
                "step" => $step,
                "question_type" => $question["question_type"],
                "correct_answer" => $question["correct_answer"],
                "question_id" => $userAnswer["question_id"],
                "question_title" => $question["question_title"],
                "question_options" => $question["question_options"]
            ];
        }
        return null;
    }


    /**
     * 发送答题
     * @param $roomId
     * @param $step
     * @param $userId
     * @param $delay
     */
    public function sendQuestion($roomId, $step, $userId, $delay = 0)
    {
        $question = $this->getQuestion($roomId, $step, $userId);
        $question["count_down"] = self::COUNT_DOWN;
        //unset($question["correct_answer"]);
        PushMessageService::getInstance()->pushByUserId("pk", "question", $question, $userId,$delay);
    }



    /**
     * 获取用户答题
     * @param $roomId
     * @param $step
     * @param $userId
     * @return array
     */
    public function getUserAnswer($roomId, $step, $userId)
    {
        return Redis::hGetAll(self::PK_ROOM_ANSWERS . ":" . $roomId . ":" . $userId . ":" . $step);
    }

    /**
     * 添加答题
     * @param $roomId
     * @param $question
     * @param $step
     * @param $count
     * @param $userId
     * @return mixed
     */
    public function addAnswer($roomId, $question, $step, $count, $userId)
    {
        $data = [
            "room_id" => $roomId,
            "step" => $step,
            "question_id" => $question["question_id"],
            "count" => $count,
            "user_answer" => "",
            "user_id" => $userId,
            "correct_answer" => $question["correct_answer"],
            "answer_start_time" => 0,
            "answer_time" => 0,
            "score" => 0,
            "is_over_time" => 0,
            "is_correct" => 0
        ];
        $ret = Redis::hMset(self::PK_ROOM_ANSWERS . ":" . $roomId . ":" . $userId . ":" . $step, $data);
        Redis::expire(self::PK_ROOM_ANSWERS . ":" . $roomId . ":" . $userId . ":" . $step,86400);
        return $ret;
    }

    /**
     * 加入到答题倒计队列
     * @param $roomId
     * @param $step
     * @param $userId
     * @return mixed
     */
    public function addAnswerQueue($roomId, $step, $userId)
    {
        $countDown = self::COUNT_DOWN;
        if($step==1){
            $countDown+=3;
        }
        Redis::hSet(self::PK_QUEUE, $roomId . "_" . $step . "_" . $userId, $countDown);
    }
}