<?php

// 这个功能个人觉着写的还不错, 代码就不删除了. 留着参考. --gwang

namespace loyalsoft;

/**
 * 评价内容
 */
class DiscussItem extends Object_ext {

    public $uid;
    public $name;
    public $msg;
    public $ts;
    public $praise;
    public $praised_uids;

    /**
     * @return int 重新计算此条评论的排行
     */
    public function Score() {
        return $this->ts + $this->praise * glc()->Hero_Discuss_Praise_weight;
    }

}

/**
 * 英雄评论模块
 * @version
 *          1.0.0 Created at 2017-3-24. by --gwang
 * @author gwang (mail@wanggangzero.cn)
 * @copyright ? 2017-3-24, SJZ LoyalSoft Corporation & gwang. All rights reserved.
 */
class HeroDiscussProc {

    /**
     * 每次请求返回的评论数量
     */
    const PageItemCount = 50;

    /**
     * [6317]发表评价
     * @param Req $req
     */
    static function Post($req) {
        $mem = $req->mem;
        $uid = $req->uid;
        $heroId = $req->paras[0];                                               # 英雄ID
        $content = $req->paras[1];                                              # 评价内容
        $item = new DiscussItem(array(#                                         # 创建一条评论
            'uid' => $uid,
            'name' => $req->userInfo->game->baseInfo->name,
            'msg' => $content,
            'ts' => now(),
            'praise' => 0, #                                                    # 赞
            'praised_uids' => ArrayInit()
        ));
        if ($mem->hexists(MemKey_GameRun::HeroDiscusses_item_hash($heroId), $uid)) {
            $item = self::_GetDiscussItem($mem, $heroId, $uid);
        } else {
            self::_SaveDiscussItem($heroId, $uid, $item);                       # 保存评论
            $mem->zadd(MemKey_GameRun::HeroDiscusses_score_zset($heroId), #
                    array($uid => $item->Score())); #                           # 写入排行数据
        }
        // todo: 添加总评论数量限制, 超过一定数量清理部分评论
        return Resp::ok(array("ret" => $item));                                 # 成功后返回评论内容,
        // ps.客户端可以对比返回的内容是否和发送的内容一致,不一致代表已经有过评论了,不可以再发布新评论, 这个设定有跟待策划商议.
    }

    /**
     * [6319] 删除评价
     * @param Req $req
     */
    static function DeletePost($req) {
        $uid = $req->uid;
        $heroId = $req->paras[0];                                               # 英雄ID
        $msg = "";
        if ($req->mem->hdel(MemKey_GameRun::HeroDiscusses_item_hash($heroId), $uid)) {
            $msg = "success";
        }
        return Resp::ok(array('ret' => $msg));
    }

    /**
     * [6320] 给英雄打分(同一个英雄只能打一次分)
     * @param Req $req
     */
    static function Score($req) {
        $uid = $req->uid;
        list($heroId, $score) = $req->paras;                                    # 提取参数:  英雄ID, 打分值
        my_Assert($score > 0 && $score <= 5, ErrCode::paras_err);               # 参数非法: 打分区间不对
//        $pubifno = $req->mem->get(MemKey_User::Union_PublicState_hash($uid)); # 玩家各区共享的数据
        $pubifno = new PublicStateModel();                                      # 玩家各区共享的数据
        $pubifno->readDataFromMem(MemKey_User::Union_PublicState_hash($uid));
        $scoredlist = $pubifno->scoredheros;
        if (is_null($scoredlist) || !is_array($scoredlist)) {
            $scoredlist = ArrayInit();
        }
        if (CommUtil::isInArray($scoredlist, $heroId)) {                        # 判断玩家是否给此英雄打过分了
            return Resp::ok(array('err' => 1, 'msg' => 'has scored!'));         # -- 业务逻辑内部错误码
        }
        // 添加打分数据,
        // 取英雄的打分数据 {cnt:xxx,totalscore:xxx}
        $heroscore = gMem()->get(MemKey_GameRun::HeroDiscusses_userScore_normal($heroId));
        if (is_null($heroscore)) {
            $heroscore = ObjectInit();
            $heroscore->amt = 0;
            $heroscore->totalscore = 0;
        }
        $heroscore->amt += 1;
        $heroscore->totalscore += $score;
        $scoredlist[] = $heroId;                                                # 玩家记录打分记录
        $pubifno->scoredheros = $scoredlist;                                    # 回存数据
        $pubifno->updateData(MemKey_User::Union_PublicState_hash($uid));

        gMem()->set(MemKey_GameRun::HeroDiscusses_userScore_normal($heroId), $heroscore);
        $newscore = $heroscore->amt > 0 ? $heroscore->totalscore / $heroscore->amt : 0;
        return Resp::ok(array('err' => 0, #                                     # 返回
                    'score' => round($newscore, 2)));
    }

    /**
     * [6316]查看评价
     * @param Req $req
     */
    static function GetDiscusses($req) {
        $heroId = $req->paras[0];                                               # 英雄ID
        $start = $req->paras[1];                                                # 起始索引
        $indexs = gMem()->zrange(MemKey_GameRun::HeroDiscusses_score_zset($heroId), #
                $start, $start + self::PageItemCount);
        $arr = gMem()->hmget(MemKey_GameRun::HeroDiscusses_item_hash($heroId), $indexs);

        $heroscore = gMem()->get(MemKey_GameRun::HeroDiscusses_userScore_normal($heroId));
        if (is_null($heroscore)) {
            $heroscore = ObjectInit();
            $heroscore->amt = 0;
            $heroscore->totalscore = 0;
        }
        $score = $heroscore->amt > 0 ? $heroscore->totalscore / $heroscore->amt : 0;
        return Resp::ok(array("ret" => $arr, 'score' => round($score, 2)));
    }

    /**
     * [6318]给评论点赞
     * @param Req $req
     */
    static function PriaseMsg($req) {
        $mem = gMem();
        $uid = $req->uid;
        $heroId = $req->paras[0];                                               # 英雄ID
        $discussId = $req->paras[1];                                            # 评论ID

        $msg = self::_GetDiscussItem($mem, $heroId, $discussId);                # 取数据
        if (!$msg) {
            return Resp::ok(array("err" => -1));                                # 评论不存在
        }
        if (isset($msg->praised_uids) && in_array($uid, $msg->praised_uids)) {
            return Resp::ok(array("err" => 1, #                                 # 已赞过
                        'praise' => $msg->praise));
        }
        $msg->praise += 1;                                                      # 点赞
        $msg->praised_uids[] = $uid;                                            # 添加点赞记录
        self ::_SaveDiscussItem($heroId, $discussId, $msg);                     # 回写数据
        $mem->zadd(MemKey_GameRun::HeroDiscusses_score_zset($heroId), #
                array($discussId => $msg->Score()));                            # 更新排名
        return Resp::ok(array("err" => 0, #                                     # 返回最新的被赞数量
                    'praise' => $msg->praise));
    }

// <editor-fold defaultstate="collapsed" desc="辅助函数">

    /**
     * 取评论
     * @param CRedisUtil $mem
     * @param string $heroId
     * @param string $discussId
     * @return DiscussItem Description
     */
    static private function _GetDiscussItem($mem, $heroId, $discussId) {
        $ret = $mem->hget(MemKey_GameRun::HeroDiscusses_item_hash($heroId), $discussId);
        if ($ret) {
            return new DiscussItem($ret);
        }
        return null;
    }

    /**
     * 回写评论
     * @param type $heroId
     * @param type $discussId
     * @param type $item
     */
    static private function _SaveDiscussItem($heroId, $discussId, $item) {
        gMem()->hset(MemKey_GameRun::HeroDiscusses_item_hash($heroId), $discussId, $item);  // 回写数据
    }

// </editor-fold>
}
