<?php
/**
 * Created by PhpStorm.
 * User: edz
 * Date: 2019-06-10
 * Time: 17:53
 */

namespace App\Repositories;


use App\Models\Behavior;
use App\Models\Post;
use App\Models\PostCollect;
use App\Models\PostComment;
use App\Models\PostData;
use App\Models\PostImgs;
use App\Models\PostLike;
use App\Models\PostShare;
use App\Models\Topic;
use App\Service\DetectionService;
use App\Service\RabbitMqUtil;
use App\Traits\PostTrait;
use App\Traits\UserTrait;
use Illuminate\Database\QueryException;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\DB;

class PostRepositories
{
    use UserTrait;
    use PostTrait;
    public function __construct(Post $post,
                                PostData $postData,
                                PostImgs $postImgs,
                                PostComment $postComment,
                                PostCollect $postCollect,
                                PostShare $postShare,
                                DetectionService $detectionService,
                                RabbitMqUtil $rabbitMqUtil,
                                Topic $topic)
    {
        $this->post = $post;
        $this->postData = $postData;
        $this->postImgs = $postImgs;
        $this->postComment = $postComment;
        $this->postCollect = $postCollect;
        $this->postShare = $postShare;
        $this->detectionService = $detectionService;
        $this->rabbitMqUtil = $rabbitMqUtil;
        $this->topic = $topic;
    }

    /**
     * 发布内容
     */
    public function create($request)
    {
        //验证小号
        $userInfo = $this->getUserInfo();
        if (empty($userInfo)) {
            Log::info('获取用户信息失败');
            return jsonError('获取用户信息失败');
        }
        $isValid = 0;
        if($userInfo['strength']){
            $isValid = 1;
        }
        $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString();
        $oneHourPostCount = $this->post->where('uid', $userInfo['uid'])->where('created_at', '>', $oneHourTime)->count();
        if($oneHourPostCount > 5){
            return jsonError('创作欲望太强啦,休息一下,看看其他用户的内容吧!');
        }

        $detectionText = $request['title'] .','. $request['content'];
        $detectionTextResult = $this->detectionService->checkText($detectionText);
        if ($detectionTextResult['code']<0) {
            return jsonError('内容违规,请修正哦');
        }

        $topicIds = json_decode($request['topic_ids'], true);
        $topicCount = count($topicIds);
        if($topicCount == 0 || $topicCount > 5){
            return jsonError('所选话题必须1-5个');
        }
        //验证话题
        $hasTopicCount = $this->topic->whereIn('id', $topicIds)->count();
        if($topicCount != $hasTopicCount){
            Log::error('所选话题非法'.$request['topic_ids']);
            return jsonError('所选话题非法');
        }
        $imgs = [];
        if($request['type'] == 'image'){
            $imgs = json_decode($request['imgs'], true);
            $imgCount = count($imgs);
            if($imgCount == 0 || $imgCount > 9){
                return jsonError('所传图集必须1-9个');
            }
        }
        $allImg = array_merge($imgs, [$request['img']]);
        $detectionImageResult = $this->detectionService->checkImg($allImg);
        if ($detectionImageResult['code']<0) {
            return jsonError('图片违规,请修正哦');
        }

        $data = [
            'uid' => $userInfo['uid'],
            'username' => $userInfo['username'],
            'mobile' => $userInfo['mobile'],
            'avatar' => $userInfo['avatar']??'',
            'type' => $request['type'],
            'img' => $request['img'],
            'video' => isset($request['video'])? $request['video'] : '',
            'topic_ids' => implode(',', $topicIds),
            'title' => isset($request['title'])? $request['title'] : '',
            'content' => $request['content'],
            'location' => isset($request['location'])? $request['location'] : '',
            'is_suggest' => 0,
            'is_hide' => 0
        ];

        $date = date('Y-m-d H:i:s');


        DB::beginTransaction();
        try{
            $post = $this->post->create($data);

            $this->postData->create([
                'post_id' => $post->id,
                'pv' => 0,
                'pv_real' => 0,
                'dislike_count' => 0,
                'praise_count' => 0,
                'praise_real_count' => 0,
                'share_count' => 0,
                'share_real_count' => 0,
                'comment_count' => 0,
                'collect_count' => 0,
                'collect_real_count' => 0,
                'available_bean' => $this->availableBean(),
                'will_collect_bean' => rand(100, 200),
                'collect_bean' => 0,
                'weight' => 0
            ]);

            if($imgs){
                $imgData = [];
                foreach($imgs as $img){
                    $imgData[] = [
                        'post_id' => $post->id,
                        'img' => $img,
                        'created_at' => $date,
                        'updated_at' => $date
                    ];
                }
                $this->postImgs->insert($imgData);
            }

            DB::commit();
            Redis::zadd('post_trigger_type', $isValid, $post->id);
            return jsonSuccess();

        }catch (QueryException $exception){
            DB::rollBack();
            Log::debug('发布内容失败:'.$exception->getMessage());
            return jsonError('发布内容失败,请重试');
        }
    }

    /**
     * 评论&回复
     */
    public function comment($request)
    {
        //验证小号
        $userInfo = $this->getUserInfo();
        if (empty($userInfo)) {
            Log::info('获取用户信息失败');
            return jsonError('获取用户信息失败');
        }

        $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString();
        $oneHourCommentCount = $this->postComment->where('uid', $userInfo['uid'])->where('created_at', '>', $oneHourTime)->count();
        if($oneHourCommentCount > 59){
            return jsonError('回复了这么多,休息休息,喝口水吧!');
        }

        $detectionTextResult = $this->detectionService->checkText($request['content']);
        if ($detectionTextResult['code']<0) {
            return jsonError('内容违规,请修正哦');
        }

        $post = $this->post->find($request['post_id']);
        if(!$post){
            return jsonError('获取内容信息失败');
        }
        $data = [
            'uid' => $userInfo['uid'],
            'post_id' => $request['post_id'],
            'parent_id' => 0,
            'username' => $userInfo['username'],
            'reply_uid' => 0,
            'reply_username' => '',
            'avatar' => $userInfo['avatar']??'',
            'content' => $request['content'],
            'is_delete' => 0,
        ];
        if(isset($request['parent_id']) && $request['parent_id'] != 0){
            $comment = $this->postComment->find($request['parent_id']);
            if(!$comment || $comment->post_id != $post->id){
                return jsonError('获取评论信息失败');
            }
            if($comment->parent_id){
                return jsonError('只能回复评论');
            }
            $data['parent_id'] = $request['parent_id'];

            if(isset($request['reply_uid']) && isset($request['reply_username'])){
                $data['reply_uid'] = $request['reply_uid'];
                $data['reply_username'] = $request['reply_username'];
                $this->rabbitMqUtil->push('add_message', [
                    'uid' => $request['reply_uid'],
                    'message_show_type' => 'post_reply_main',
                    'param' => [
                        'uid' => $userInfo['uid'],
                        'username' => $userInfo['username'],
                        'post_id' => $post->id,
                        'content' => subtext($request['content'], 20),
                    ]
                ]);
            }else{
                $data['reply_uid'] = 0;
                $data['reply_username'] = '';
                $this->rabbitMqUtil->push('add_message', [
                    'uid' => $comment->uid,
                    'message_show_type' => 'post_reply',
                    'param' => [
                        'uid' => $userInfo['uid'],
                        'username' => $userInfo['username'],
                        'post_id' => $post->id,
                        'content' => subtext($request['content'], 20),
                    ]
                ]);
            }
        }else{
            $this->rabbitMqUtil->push('add_message', [
                'uid' => $post->uid,
                'message_show_type' => 'post_comment',
                'param' => [
                    'uid' => $userInfo['uid'],
                    'username' => $userInfo['username'],
                    'post_id' => $post->id,
                    'content' => subtext($request['content'], 20),
                ]
            ]);
        }

        DB::beginTransaction();
        try{
            $comment = $this->postComment->create($data);
            $post->data->comment_count += 1;
            $post->data->save();

            DB::commit();
            return jsonSuccess(['id' => $comment->id], '评论成功');

        }catch (QueryException $exception){
            DB::rollBack();
            Log::debug('评论内容失败:'.$exception->getMessage());
            return jsonError('评论内容失败,请重试');
        }
    }

    /**
     * 内容列表
     */
    public function lists($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        return $this->post
            ->join('post_data', 'post_data.post_id', '=', 'post.id')
            ->select('post.*')
            ->where(function($query) use ($request){
                if(isset($request['keyword'])){
                    $query->where('title', 'like', "%{$request['keyword']}%")
                        ->orWhere('content', 'like', "%{$request['keyword']}%");
                }
            })
            ->where(function($query) use ($request){
                if(isset($request['topic_ids'])){
                    $topicIds = json_decode($request['topic_ids'], true);
                    foreach ($topicIds as $key=>$id) {
                        if ($key==0) {
                            $query->whereRaw('FIND_IN_SET('.$id.', post.topic_ids)');
                        } else {
                            $query->orWhereRaw('FIND_IN_SET('.$id.', post.topic_ids)');
                        }
                    }
                }
            })
            ->orderBy('weight','desc')
            ->paginate($perPage);
    }

    /**
     * 视频列表
     */
    public function video($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        $where = [];
        if(isset($request['id'])){
            $where[] = ['post.id', '<>', $request['id']];
        }
        $where[] = ['type', 'video'];
        return $this->post
            ->join('post_data', 'post_data.post_id', '=', 'post.id')
            ->select('post.*')
            ->where($where)
            ->orderBy('weight','desc')
            ->paginate($perPage);
    }

    /**
     * 个人中心内容列表
     */
    public function MyPost($type, $uid)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        $where = [];
        if($type == 'create'){
            $where[] = ['post.uid', $uid];
            $post = $this->post;
            $order = 'post.id';
        }elseif($type == 'collect'){
            $post = $this->post->join('post_collect', 'post_collect.post_id', '=', 'post.id');
            $where[] = ['post_collect.uid', $uid];
            $order = 'post_collect.id';
        }else{
            $post = $this->post->join('post_share', 'post_share.post_id', '=', 'post.id');
            $where[] = ['post_share.uid', $uid];
            $order = 'post_share.updated_at';
        }
        return $post
            ->join('post_data', 'post_data.post_id', '=', 'post.id')
            ->select('post.*')
            ->where($where)
            ->orderBy($order,'desc')
            ->paginate($perPage);
    }

    /**
     * 内容详情
     */
    public function detail($id)
    {
        return $this->post
            ->join('post_data', 'post_data.post_id', '=', 'post.id')
            ->select('post.*')
            ->find($id);
    }

    /**
     * 推荐内容列表
     */
    public function suggestPost($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        return $this->post
            ->join('post_data', 'post_data.post_id', '=', 'post.id')
            ->select('post.*')
            ->orderBy('weight','desc')
            ->paginate($perPage);
    }

    /**
     * 话题内容
     */
    public function topicPost($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        return $this->post
            ->join('post_data', 'post_data.post_id', '=', 'post.id')
            ->select('post.*')
            ->whereRaw('FIND_IN_SET(' . $request['id'] . ',post.topic_ids)')
            ->orderBy('id','desc')
            ->paginate($perPage);
    }


    /**
     * 评论列表
     */
    public function commentList($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        return $this->postComment
            ->where('post_id', $request['post_id'])
            ->where('parent_id', 0)
            ->orderBy('id','desc')
            ->paginate($perPage);
    }

    /**
     * 回复列表
     */
    public function replyList($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        return $this->postComment
            ->where('parent_id', $request['id'])
            ->orderBy('id','desc')
            ->paginate($perPage);
    }

    /**
     * 话题列表
     */
    public function topicList($request)
    {
        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;

        $where = [];
        if(isset($request['category_id'])){
           $topic = $this->topic->join('category_topic', 'category_topic.topic_id', '=', 'topic.id')->select('topic.*');
           $where[] = ['category_topic.category_id', $request['category_id']];
        }else{
            $topic = $this->topic;
        }
        if(isset($request['is_suggest'])){
            $where[] = ['topic.is_suggest', $request['is_suggest']];
        }
        return $topic
            ->where($where)
            ->orderBy('id','desc')
            ->paginate($perPage);
    }


    /**
     * 更新帖子统计数量
     * @param $request
     * @return mixed
     */
    public function updatePostData($request)
    {
        $postId = isset($request['post_id'])?$request['post_id']:0;
        if(empty($postId)){
            Log::debug("非帖子类操作,不操作帖子统计数量".json_encode($request));
            return true;
        }
        $post = PostData::where('post_id', $postId)->first();
        if (isset($request['behavior_flag']) && $request['behavior_flag'] == 'read') {
            $post->pv += 1;
            $post->pv_real += 1;
            Log::debug("帖子:".$postId."被阅读,pv +1");
        } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'unlike') {
            $post->dislike += 1;
            Log::debug("帖子:".$postId."被不喜欢,unlike +1");
        } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'like') {
            if($request['behavior_value']){
                $post->praise_count += 1;
                $post->praise_real_count += 1;
                PostLike::create(['uid'=>$request['target_id'],'post_id'=>$request['post_id']]);
                Log::debug("帖子:".$postId."被点赞,praise_count +1");
            }else{
                $post->praise_count -= 1;
                $post->praise_real_count -= 1;
                PostLike::where(['uid'=>$request['target_id'],'post_id'=>$request['post_id']])->delete();
                Log::debug("帖子:".$postId."被取消点赞,praise_count -1");
            }
        } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'forward') {
            $post->share_count += 1;
            $post->share_real_count += 1;
            $shareRow = PostShare::where(['uid'=>$request['target_id'],'post_id'=>$request['post_id']])->first();
            if($shareRow){
                PostShare::where(['uid'=>$request['target_id'],'post_id'=>$request['post_id']])->update(['uid'=>$request['target_id'],'post_id'=>$request['post_id']]);
            }else{
                PostShare::create(['uid'=>$request['target_id'],'post_id'=>$request['post_id']]);
            }
            Log::debug("帖子:".$postId."被分享,share_count +1");
        } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'comment') {
            $post->comment_count += 1;
            Log::debug("帖子:".$postId."被评论,comment_count +1");
        } elseif (isset($request['behavior_flag']) && $request['behavior_flag'] == 'collect') {
            if($request['behavior_value']) {
                $post->collect_count += 1;
                $post->collect_real_count += 1;
                PostCollect::create(['uid'=>$request['target_id'],'post_id'=>$request['post_id']]);
                Log::debug("帖子:".$postId."被收藏,collect_count +1");
            }else{
                $post->collect_count -= 1;
                $post->collect_real_count -= 1;
                PostCollect::where(['uid'=>$request['target_id'],'post_id'=>$request['post_id']])->delete();
                Log::debug("帖子:".$postId."被取消收藏,collect_count -1");
            }
        }
        $this->collectPostId($request['post_id']);
        return $post->save();
    }

    /**
     * 收集所有有操作的帖子,存入redis
     * 供后续计算帖子权重
     * @param $id
     */
    public function collectPostId($id)
    {
        $key = "community_calc_post_score";
        Redis::sadd($key,$id);
        Log::debug('存入帖子'.$id.'到权重列表');
    }


    /**
     * 话题详情
     */
    public function topicDetail($id)
    {
        return $this->topic
            ->find($id);
    }


}