<?php
/**
 *  ╔═══════════════════════════════════════════════════╗
 *  ║                                                   ║
 *  ║     ██╗  ██╗   █████╗    ██████╗                  ║
 *  ║     ██║  ██║  ██╔══██╗  ██╔═══██╗                 ║
 *  ║     ███████║  ███████║  ██║   ██║                 ║
 *  ║     ██╔══██║  ██╔══██║  ██║   ██║                 ║
 *  ║     ██║  ██║  ██║  ██║  ╚██████╔╝   SNS           ║
 *  ║                                                   ║    
 *  ║                                                   ║    
 *  ║     © 2023 HaoSNS™ All Rights Reserved            ║
 *  ║     官方网站: https://www.haosns.com                *
 *  ║     本代码由赣州乐易网络科技有限公司®提供             *
 *  ║                                                    *
 *  ║   未经授权禁止复制、传播或用于其他商业目的            *
 *  ║                                                   ║
 *  ╚═══════════════════════════════════════════════════╝
 */


namespace app\api\lists;

use app\common\enum\PayEnum;
use app\common\model\Article;
use app\common\model\ArticleOrder;
use app\common\model\Circle;
use app\common\model\CircleOrder;
use app\common\model\UserCollect;
use app\common\model\UserFollow;
use app\common\service\ConfigService;
use app\api\logic\ArticleLogic;
use app\common\enum\ArticleEnum;
use app\common\service\FileService;
use app\common\service\map\TencentService;

class ArticleLists extends BaseShopDataLists
{

    /**
     * @notes 设置搜索
     */
    public function setSearch()
    {
        $this->searchWhere[] = [
            'status',
            '=',
            1
        ];

        $this->searchWhere[] = [
            'is_show',
            '=',
            1
        ];

        $this->searchWhere[] = [
            'is_open',
            '=',
            1
        ];



        if (isset($this->params['circle_id']) && $this->params['circle_id']) {
            if ($this->params['circle_id'] == 'video') {
                $this->searchWhere[] = [
                    ['type', '=', ArticleEnum::TYPE_VIDEO]
                ];

            } else {
                $this->searchWhere[] = [
                    ['circle_id', '=', $this->params['circle_id']]
                ];
            }
        }

        // 圈子子分类
        if (isset($this->params['sub_category_id'])) {
            $this->searchWhere[] = [
                ['sub_category_id', '=', $this->params['sub_category_id']]
            ];
        }

        // 推荐
        if (isset($this->params['type']) && $this->params['type'] == 'is_recomment') {
            $this->searchWhere[] = [
                ['is_recomment', '=', 1]
            ];
        }

        // 热门
        if (isset($this->params['type']) && $this->params['type'] == 'is_top') {
            $this->searchWhere[] = [
                ['is_top', '=', 1]
            ];
        }


        // 指定用户下的
        if (isset($this->params['user_id']) && $this->params['user_id']) {

            if (isset($this->params['type']) && !in_array($this->params['type'], ['like', 'user_collect'])) {
                $this->searchWhere[] = [
                    'a.user_id',
                    '=',
                    $this->params['user_id']
                ];
            }

            if (!isset($this->params['type'])) {
                $this->searchWhere[] = [
                    'a.user_id',
                    '=',
                    $this->params['user_id']
                ];
            }


        }

        // 只看圈主
        if (isset($this->params['type']) && $this->params['type'] == 'circle_user') {
            $circle = \app\common\model\Circle::find($this->params['circle_id']);
            if($circle){
                $this->searchWhere[] = [
                'user_id',
                '=',
                $circle->user_id,
            ];
            }
        }

        // 最小经度
        if (isset($this->params['min_longitude'])) {
                $this->searchWhere[] = [
                'longitude',
                '>',
                $this->params['min_longitude'],
            ];
        }
        // 最大经度
        if (isset($this->params['max_longitude'])) {
                $this->searchWhere[] = [
                'longitude',
                '<',
                $this->params['max_longitude'],
            ];
        }

        // 最小纬度
        if (isset($this->params['min_latitude'])) {
               $this->searchWhere[] = [
               'latitude',
               '>',
               $this->params['min_latitude'],
           ];
       }
       // 最大纬度
       if (isset($this->params['max_latitude'])) {
               $this->searchWhere[] = [
               'latitude',
               '<',
               $this->params['max_latitude'],
           ];
       }


        // 同城
        if (isset($this->params['type']) && $this->params['type'] == 'region') {

            if (isset($this->params['city'])) {
                // 根据地区查询
                $this->searchWhere[] = [
                    'a.city_json',
                    'like',
                   '%'. $this->params['city'].'%'
                ];
            } elseif (isset($this->params['latitude']) && isset($this->params['longitude'])) {
                // 根据经纬度查询
                $geoAddress = TencentService::geocoder($this->params['latitude'], $this->params['longitude']);
                if ($geoAddress) {
                    $this->searchWhere[] = [
                        'a.region',
                        '=',
                        $geoAddress['address_component']['city']
                    ];
                }
            }else{
                // 根据ip查同城
                $ip = $_SERVER['REMOTE_ADDR'];
                $ip_address = '';
                try {
                    // 初始化，指定QQWry.dat文件路径
                    $qqwry = new \app\common\service\QQWry('qqwry.dat');
                    // 获取客户端IP
                    $ip = $_SERVER['REMOTE_ADDR'];
                    // 查询IP地理位置
                    $location = $qqwry->getLocation($ip);
                    $ip_address = $location['country'];

                    $this->searchWhere[] = [
                        'ip_address',
                        'like',
                        '%' . $ip_address . '%'
                    ];

                } catch (\Exception $e) {
                    // echo "发生错误: " . $e->getMessage();
                    return show(0, '没有数据');
                }
            }


        }

        // 图片
        if (isset($this->params['is_image']) && $this->params['is_image'] == 1) {
            $this->searchWhere[] = [
                ['image', '!=', '']
            ];
        }

        // 视频
        if (isset($this->params['is_video']) && $this->params['is_video'] == 1) {
            $this->searchWhere[] = [
                ['video', '!=', '']
            ];
        }

        // 预设标签搜索
        if (isset($this->params['label'])) {
            $this->searchWhere[] = [
                ['label', 'like', '%'.$this->params['label'].'%']
            ];
        }


    }

    /**
     * 设置排序
     */
    public function setOrder()
    {

        $article_index_sort = ConfigService::get('article', 'article_index_sort', 1);

        // 设置默认排序方式， 按时间 还是 按照热度
        if ($article_index_sort == 1) {
            $this->orderBy = 'a.create_time desc , a.sort desc';
        } else {
            $this->orderBy = 'a.visit desc , a.sort desc';
        }

        if (isset($this->params['type']) && $this->params['type'] == 'is_news') {
            $this->orderBy = 'a.polish_time desc,a.update_time desc,a.create_time desc , a.sort desc';
        }

        if (isset($this->params['type']) && $this->params['type'] == 'is_like') {
            $this->orderBy = 'collect_count desc';
        }

        $this->orderBy .= ',a.polish_time desc';

        return $this->orderBy;

    }


    /**
     * @notes 文章/帮助列表
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function lists(): array
    {
        $user = null;
        if($this->userId){
            $user = \app\common\model\User::find($this->userId);
        }

        $this->setSearch();

        // 判断是否付费内容
        if (!empty($this->request->get('circle_id'))) {

            // 判断需要vip才能访问
            $circle_inof = Circle::with('vipLevel')
                ->find($this->request->get('circle_id'));
            // dd($circle_inof->vipLevel);
            // vip判断
            if ($circle_inof && $circle_inof->vipLevel) {
                $user = \app\common\model\User::with('vipInfo')->find($this->userInfo);
                // 判断vip是否到期
                if ($user->vip_expire_time < time()) {
                    throw new \Exception('没有vip或到期');
                }
                // 判断我是否有vip权限
                if ($user->vipInfo->rank < $circle_inof->vipLevel->rank) {
                    throw new \Exception('vip等级不够');
                }
            }

            // 判断当前圈子是否收费
            if ($circle_inof['subscription_price'] > 0) {
                if ($this->userId) {
                    // 判断该用户是否已经付费 
                    $order = CircleOrder::where(['pay_status' => PayEnum::ISPAID, 'circle_id' => $this->request->get('circle_id'), 'user_id' => $this->userId])->count();
                    if (!$order) {
                        // echo '未购买';die;
                        return [];
                    }
                } else {
                    // 请登录
                    return [];
                }
            }
        }

        $with =[
            'user' => function ($query) {
                $query->with('user_level');
            },
            // 'circleLevel',
            'vote',
            'circle',
        ];
        $lists = Article::alias('a')->with($with)
            ->where($this->searchWhere)
            ->limit($this->limitOffset, $this->limitLength)
            ->append(['comment_num', 'collect_num', 'zan_num'])
            ->leftJoin('user_collect uc', 'a.id = uc.aid')
            ->group('a.id')
            ->field('a.*, COUNT(uc.id) as collect_count');

        if (isset($this->params['sort']) && $this->params['sort'] == 'rand') {
            $lists = $lists->order(\think\facade\Db::raw('RAND()'));
        } else {
            $lists = $lists->order($this->setOrder());
        }

        $lists = $lists->order(\think\facade\Db::raw('RAND()'));

        // 关键词搜索
        if (isset($this->params['keyword']) && $this->params['keyword']) {
            
            checkDangerTxt($this->params['keyword']);
            
            $pinyin = new \Overtrue\Pinyin\Pinyin();
            $this->params['keyword_pinyin'] = $pinyin->permalink($this->params['keyword'], '');
            $lists->join('user u', 'u.id = a.user_id')
                ->where(function ($query) {
                    $query->where('u.nickname', '=', $this->params['keyword']);
                    $query->whereOr('a.title', 'like', '%' . $this->params['keyword'] . '%');
                    $query->whereOr('a.content', 'like', '%' . $this->params['keyword'] . '%');
                    $query->whereOr('a.title_pinyin', 'like', '%' . $this->params['keyword_pinyin'] . '%');
                    $query->whereOr('a.content_pinyin', 'like', '%' . $this->params['keyword_pinyin'] . '%');
                });

            // 有无搜索
            $search = \app\common\model\SearchLog::where('keyword',$this->params['keyword'])->find();

            if($search){
                // 增加搜索次数
                $search->num = $search->num+1;
                $search->save();
            }else{
                // 记录搜索日志
                $search_log = [
                    'user_id'=>$this->userId,
                    'keyword'=>$this->params['keyword'],
                    'search_type'=>'article',
                    'ip_address'=>$this->request->ip(),
                ];
                \app\common\model\SearchLog::create($search_log);
            }
            

        }
        // 话题
        if (isset($this->params['topic_id']) && $this->params['topic_id']) {
            $lists->whereRaw("FIND_IN_SET({$this->params['topic_id']},topic_ids)");
        }

        // 个人关注的帖子
        if (isset($this->params['type']) && $this->params['type'] == 'collect') {
            $lists->join('user_follow uf', 'uf.follow_user_id = a.user_id')->where(['uf.user_id' => $this->userId]);
        }else{    
            // 仅关注粉丝可见
            $this->searchWhere[]=['only_look_follow','=',0];
        }


        // 喜欢的 ，点赞的
        if (isset($this->params['type']) && $this->params['type'] == 'like') {
            // $user = \app\common\model\User::find($this->params['user_id']);
            if ($user->private_like == 1) {
                 throw new \think\Exception('对方设置了隐私');
            }

            $lists->join('user_collect uc', 'uc.aid = a.id')->where([
                'uc.user_id' => $this->params['user_id'],
                'uc.type' => 2
            ]);
        }

        // 用户收藏
        if (isset($this->params['type']) && $this->params['type'] == 'user_collect') {
            $user = \app\common\model\User::find($this->params['user_id']);
            if ($user->private_collect == 1) {
                 throw new \think\Exception('对方设置了隐私');
            }
            $lists->join('user_collect uc', 'uc.aid = a.id')->where([
                'uc.user_id' => isset($this->params['user_id']) ? $this->params['user_id'] : $this->userId,
                'uc.type' => 1
            ]);
        }

        // 当前登录判断 显示公开 非公开记录
        if (isset($this->params['user_id']) && $this->params['user_id']) {
            if (isset($this->params['type']) && !in_array($this->params['type'], ['like', 'user_collect'])) {
                if ($this->userId) {
                    $lists->whereRaw(" (a.user_id = {$this->userId} ) or  ( a.is_open = 1  and a.user_id <> {$this->userId}   ) ");
                } else {
                    // 公开的，
                    $lists->where('is_open', 1);
                }
            }
        }

        // 字段搜索条件
        if (isset($this->params['field_values'])) {
            $field_like = [];
            foreach (explode(',', $this->params['field_values']) as $v) {
                $field_like[] = '%,' . $v . ',%';
            }
            $field_where = [
                [
                    'field_values',
                    'like',
                    $field_like
                ]
            ];
            $lists->where($field_where);
        }

        $lists = $lists->select()->toArray();

        if(isActivePluginByPluginName('pin')){

            // 广告位帖子置顶
            //需要加载广告
            if ($this->params['page_no'] == 1 && isset($this->params['require_ad']) && $this->params['require_ad']==1) {

                // 查询广告位帖子
                if (isset($this->params['circle_id']) && !empty($this->params['circle_id'])) {
                    // 圈子内置顶帖子
                    $position = \app\common\model\PinPosition::where('code', 'circle_article')->find();
                } else {
                    // 首页置顶帖子
                    $position = \app\common\model\PinPosition::where('code', 'index_article')->find();
                }

               if(isset($position) && !empty($position)){
                    $record_article_ids = \app\common\model\PinRecord::where([
                        ['start_time', '<', time()],
                        ['end_time', '>', time()],
                        ['position_id', '=', $position->id]
                    ])
                    ->select()
                    ->column('article_id');

                // dd($record_article_ids);

                if (!empty($record_article_ids)) {
                    // echo '查询推广的帖子';die;
                    $pin_article_list = \app\common\model\Article::with($with)
                    ->where('id', 'in', $record_article_ids)
                        ->order('polish_time', 'desc')
                        ->append(['comment_num', 'collect_num', 'zan_num'])
                        ->select()
                        ->toArray();

                    // dd($pin_article_list);

                    foreach ($pin_article_list as &$v) {
                        $v['ad'] = 1;
                    }

                    // $lists = $pin_article_list + $lists;
                    $lists = array_merge($pin_article_list,$lists);

                    // dd($lists);
                }
               };
                

            }
        }
        

        foreach ($lists as $k=>&$item) {

            // 帖子字段
            if(isActivePluginByPluginName('field')){
                $item['field'] = \think\facade\Db::table(config('database.connections.mysql.prefix').'article_field')
                ->where('article_id',$item['id'])
                ->alias('a')
                ->join('circle_field c', 'a.field_id = c.id')
                ->field('a.value as article_value,a.*, c.*')
                ->select()
                ->toArray();
            }

            // 互动人数统计
            $comment_count = \app\common\model\ArticleComment::where('aid',$item['id'])
            ->group('user_id')
            ->count();
            $vote_ids = \app\common\model\Vote::where('article_id',$item['id'])->column('id');
            $vote_count =\app\common\model\VoteLog::where('vote_id','in',$vote_ids)
            ->group('user_id')
            ->count();
            $item['interaction'] = $comment_count + $vote_count;
    

            $item['circle_level']=[];
            if(isset($this->params['circle_id']) && !empty($this->params['circle_id'])){
                $item['circleLevel'] = \app\common\model\CircleLevel::with(['circleUserLevel'])
                ->where('circle_id',$this->params['circle_id'])
                ->where('user_id',$this->userId)
                ->find();

                // 查询我在这个圈子里的等级
                // foreach($item['circleLevel'] as $k=>&$v){
                //     if($v['circle_id']==$this->params['circle_id']){
                //         unset($item['circleLevel'][$k]);
                //     }else{
                //         $item['circle_level']=$v;
                //     }
                // }
            }
            

            // $item['beforTime'] = beforTime($item['create_time']);

            $item['video_cover'] = $item['video_cover'] ? FileService::getFileUrl($item['video_cover']) : '';
            $item['video'] = $item['video'] ? FileService::getFileUrl($item['video']) : '';
            $item['create_time'] = formatTime($item['create_time']);

            if ($this->userId) {

                if(!empty($item['vote'])){
                    foreach($item['vote'] as &$v){
                        foreach($v['options'] as &$o){
                            $res=\app\common\model\VoteLog::where([
                                ['user_id','=',$this->userId],
                                ['vote_options_id','=',$o['id']],
                            ])->find();
                             if($res){
                                $o['is_select']=1;
                            }else{
                                $o['is_select']=0;
                            }
                        } 
                    }
                }
                
                //是否点赞过
                $isAan = UserCollect::where(['type' => 2, 'aid' => $item['id'], 'user_id' => $this->userId])->value('id');
                $item['is_zan'] = $isAan ? 1 : 0;

                //是否收藏过
                $isCollect = UserCollect::where(['type' => 1, 'aid' => $item['id'], 'user_id' => $this->userId])->value('id');
                $item['is_collect'] = $isCollect ? 1 : 0;

                //是否关注过改帖子用户
                $isFollow = UserFollow::where(['follow_user_id' => $item['user_id'], 'user_id' => $this->userId])->value('id');
                $item['is_follow'] = $isFollow ? 1 : 0;

                $item['btn']['follow_btn'] = $this->userId == $item['user_id'] ? 0 : 1;
                // 判断帖子发帖人时，可管理帖子
                $item['btn']['manage'] = $this->userId == $item['user_id'] ? 1 : 0;


                // 判断是否付费内容
                if ($item['pay_money'] > 0 && $item['user_id']!=$this->userId) {
                    // 判断该用户是否已经付费 
                    $order = ArticleOrder::where(['pay_status' => PayEnum::ISPAID, 'article_id' => $item['id'], 'user_id' => $this->userId])->count();
                    if (!$order) {
                        // 截取部分内容
                        $item['title'] = empty($item['title'])?mb_substr($item['content'],0,6):$item['title'];
                        $item['content'] = ArticleLogic::cuttingPayContent($item['content']);
                        // $item['image'] = [];
                        $data['image'] = isset($data['image'][0]) ? [$data['image'][0]] : [];
                        $item['video'] = '';
                        $item['is_pay'] = 0;
                        
                        $item['cloud_password'] = '付费后显示';
                        $item['cloud_url'] = '付费后显示';
                    } else {
                        $item['is_pay'] = 1;
                    }
                }

                if($item['user_id'] != $this->userId){
                    // 不给谁看
                    if(!empty($item['disable_look_user_ids'])){
                        $disable_look_user_ids = explode(',',$item['disable_look_user_ids']);
                        if(in_array($this->userId,$disable_look_user_ids)){
                            unset($lists[$k]);
                        }
                    }

                    // 只给谁看
                    if(!empty($item['only_look_user_ids'])){
                        $only_look_user_ids = explode(',',$item['only_look_user_ids']);
                        if(!in_array($this->userId,$only_look_user_ids)){
                            unset($lists[$k]);
                        }
                    }

                    // 多少级可见
                    if($item['only_look_user_level'] >0){
                        if($user->level < $item['only_look_user_level']){
                            unset($lists[$k]);
                        }
                    }
                }

            } else {
                $item['btn']['follow_btn'] = 1;

                // 权限判断未登录不显示
                if(!empty($item['only_look_user_ids'])  || !empty($item['disable_look_user_ids']) || $item['only_look_user_level']>0 || $item['only_look_follow']==1 ){
                    unset($lists[$k]);
                }

                // 判断是否付费内容
                if ($item['pay_money'] > 0) {
                    // 截取部分内容
                    $item['title'] = empty($item['title'])?mb_substr($item['content'],0,6):$item['title'];
                    $item['content'] = ArticleLogic::cuttingPayContent($item['content']);
                    $item['image'] = [];
                    $item['video'] = '';
                    $item['is_pay'] = 0;
                    $item['cloud_password'] = '付费后显示';
                    $item['cloud_url'] = '付费后显示';
                }
            }

        }

        $lists = array_values($lists);

        return $lists;
    }

    /**
     * @notes 文章/帮助总记录数
     * @return int
     */
    public function count(): int
    {
        $this->setSearch();

        $count = Article::alias('a')->where($this->searchWhere);

        // 关键词搜索
        if (isset($this->params['keyword']) && $this->params['keyword']) {
            $pinyin = new \Overtrue\Pinyin\Pinyin();
            $this->params['keyword_pinyin'] = $pinyin->permalink($this->params['keyword'], '');
            $count->join('user u', 'u.id = a.user_id')
                ->where(function ($query) {
                    $query->where('u.nickname', '=', $this->params['keyword']);
                    $query->whereOr('a.title', 'like', '%' . $this->params['keyword'] . '%');
                    $query->whereOr('a.title_pinyin', 'like', '%' .$this->params['keyword_pinyin']. '%');
                    $query->whereOr('a.title_pinyin', 'like', '%' . $this->params['keyword_pinyin'] . '%');
                });
        }

        // 话题
        if (isset($this->params['topic_id']) && $this->params['topic_id']) {
            $count->whereRaw("FIND_IN_SET({$this->params['topic_id']},topic_ids)");
        }

        // 个人关注的帖子
        if (isset($this->params['type']) && $this->params['type'] == 'collect') {
            $count->join('user_follow uf', 'uf.follow_user_id = a.user_id')->where(['uf.user_id' => $this->userId]);
        }

        // 喜欢的 ，点赞的
        if (isset($this->params['type']) && $this->params['type'] == 'like') {
            $count->join('user_collect uc', 'uc.aid = a.id')->where([
                'uc.user_id' => $this->params['user_id'],
                'uc.type' => 2
            ]);
        }

        // 用户收藏
        if (isset($this->params['type']) && $this->params['type'] == 'user_collect') {
            $count->join('user_collect uc', 'uc.aid = a.id')->where([
                'uc.user_id' => isset($this->params['user_id']) ? $this->params['user_id'] : $this->userId,
                'uc.type' => 1
            ]);
        }

        if (isset($this->params['user_id']) && $this->params['user_id']) {
            if (isset($this->params['type']) && !in_array($this->params['type'], ['like', 'user_collect'])) {
                // 当前登录判断 显示公开 非公开记录
                if ($this->userId) {
                    $count->whereRaw(" (a.user_id = {$this->userId} ) or  ( a.is_open = 1  and a.user_id <> {$this->userId}   ) ");

                } else {
                    // 公开的，
                    $count->where('is_open', 1);
                }
            }
        }
        

        // 当前登录判断 显示公开 非公开记录
        if (isset($this->params['user_id']) && $this->params['user_id']) {
            if (isset($this->params['type']) && !in_array($this->params['type'], ['like', 'user_collect'])) {
                if ($this->userId) {
                    $count->whereRaw(" (a.user_id = {$this->userId} ) or  ( a.is_open = 1  and a.user_id <> {$this->userId}   ) ");
                } else {
                    // 公开的，
                    $count->where('is_open', 1);
                }
            }
        }

        // 字段搜索条件
        if (isset($this->params['field_values'])) {
            $field_like = [];
            foreach (explode(',', $this->params['field_values']) as $v) {
                $field_like[] = '%,' . $v . ',%';
            }
            $field_where = [
                [
                    'field_values',
                    'like',
                    $field_like
                ]
            ];
            $count->where($field_where);
        }

        return $count->count();
    }
}