<?php

namespace App\Services\Api;

use App\Models\BlackList;
use App\Models\CourseUser;
use App\Models\GameUser;
use App\Models\TeamUser;
use App\Models\User;
use App\Models\UserExtra;
use App\Models\UserFollow;
use App\Models\UserFriend;
use App\Models\MobilePrefix;
use App\Models\UserIdentify;
use App\Models\UserIntegral;
use App\Services\JPushService;
use App\Services\TencentImAccountService;
use App\Services\TencentImGroupService;
use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Redis;
use PHPUnit\Util\Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class UserService
{
    public function __construct()
    {
        $this->user = auth('api')->user();
        $this->GameService = new GameService();
    }

    //获取用户信息
    public static function getUserInfo($user_id)
    {
        $info = User::where('id', $user_id)
            ->whereNull('deleted_at')
            ->first();
        if (!$info) {
            return [];
        }
        $info = $info->toArray();
        $info['wx_openid'] = $info['wx_openid'] ? 1 : 0;
        $info['fb_openid'] = $info['fb_openid'] ? 1 : 0;
        $info['apple_openid'] = $info['apple_openid'] ? 1 : 0;
        $info['have_user_course'] = UserService::haveUserCourse($info['id']);

        return $info;
    }

    //用户详情
    public function userDetail($user_id)
    {
        //查询用户信息  和好友数量，粉丝数量，关注数量
        $userInfo = (new User())->setTable('u')->from('users as u')
            ->where('id', $user_id)
            ->leftJoin('user_extras as ue', 'u.id', '=', 'ue.user_id')
            ->select(['u.id', 'u.name', 'u.avatar', 'u.sex', 'u.is_auth', 'u.bg', 'u.tencent_im_user_id', 'u.usga', 'u.ball_age',
                'ue.friends_count', 'ue.fans_count', 'ue.follow_count'])
            ->first();

        //比赛场次
        $totalGames = (new GameUser())->setTable('gu')->from('game_users as gu')
            ->join('games as g', 'g.id', '=', 'gu.game_id')
            ->where('gu.user_id', $user_id)
            ->where('gu.type', 1)
            ->whereNull('gu.deleted_at')
            ->whereNotNull('g.end_time')
            ->count();

        $userInfo['total_games'] = $totalGames;

        //本月以前的打过球的最近月份的 月份最佳总干
        $monthGameIds = $this->GameService->getGameMonth($user_id);
        if (!empty($monthGameIds)) {
            $recentMonth = max(array_column($monthGameIds, 'month'));
            $info = $this->GameService->getMonthBestScore($recentMonth, $user_id);
            $userInfo['recent_best_score'] = isset($info['total_score']) ? $info['total_score'] : 0;
        } else {
            $userInfo['recent_best_score'] = 0;
        }

        if ($user = auth('api')->user()) {
            //查询是否关注此人
            $isFollow = UserFollow::query()->where([
                'user_id' => $user->id,
                'target_id' => $user_id,
                'status' => 1
            ])->first();
            $userInfo['is_follow'] = $isFollow ? 1 : 0;
            $isFollow2 = UserFollow::query()->where([
                'user_id' => $user_id,
                'target_id' => $user->id,
                'status' => 1
            ])->first();

            if ($isFollow && $isFollow2) {
                $userInfo['is_follow'] = 2;
            }
        }
        $userInfo['have_user_course'] = self::haveUserCourse($user_id);
        //查询会员球场
        $userInfo['course_user_list'] = (new CourseService())->getUserCourseList(1, $user_id);
        //查询球队列表
        $teamService = new TeamService();
        $userInfo['team_list'] = $teamService->getMyTeams($user_id);
        $userInfo['team_count'] = count($userInfo['team_list']);

        return $userInfo;
    }

    //是否有会员球场
    public static function haveUserCourse($userId)
    {
        $info = CourseUser::query()
            ->where('user_id', $userId)
            ->where('status', '>', 0)
            ->whereNull('deleted_at')
            ->first();
        if (!$info) {
            return 0;
        }

        return 1;
    }

    //总场次
    public function totalGames()
    {
        $count = (new GameUser())->setTable('gu')->from('game_users as gu')
            ->join('games as g', 'g.id', '=', 'gu.game_id')
            ->where('gu.user_id', $this->user->id)
            ->where('gu.type', 1)
            ->whereNull('gu.deleted_at')
            ->whereNotNull('g.end_time')
            ->count();

        return $count;
    }

    //历史最佳总杆
    public function historyBestPar($user_id)
    {
        $gameService = new GameService();
        $gameMonths = $gameService->getGameMonth($user_id);
        if (empty($gameMonths)) {
            return 0;
        }
        $months = array_column($gameMonths, 'month');
        $list = [];
        $months = array_unique($months);

        foreach ($months as $month) {
            $list[] = $gameService->getMonthBestScore($month, $user_id);
        }
        $list = array_values(array_filter($list));

        $sort_key = array_column($list, 'total_score');

        array_multisort($sort_key, SORT_ASC, $list);

        return array_shift($list);
    }

    //打过的球场数
    public function historyCourses()
    {
        $course_ids = (new GameUser())->setTable('gu')->from('game_users as gu')
            ->join('games as g', 'g.id', '=', 'gu.game_id')
            ->join('courses as c', 'c.id', '=', 'g.course_id')
            ->where('gu.user_id', $this->user->id)
            ->where('gu.type', 1)
            ->whereNull('c.deleted_at')
            ->whereNull('gu.deleted_at')
            ->whereNotNull('g.end_time')
            ->groupBy('c.id')
            ->pluck('c.id');

        $count = !empty($course_ids) ? count($course_ids) : 0;

        return $count;
    }

    //我的球队数
    public function teamCount()
    {
        $teamCount = (new TeamUser())->setTable('tu')->from('team_users as tu')
            ->join('teams as t', 't.id', '=', 'tu.team_id')
            ->where('tu.user_id', $this->user->id)
            ->whereNull('t.deleted_at')
            ->whereNull('tu.deleted_at')
            ->count();

        return $teamCount;
    }

    //用户 好友、关注、粉丝等数据
    public function userExtra()
    {
        if (!$info = UserExtra::where('user_id', $this->user->id)->first()) {
            $userExtra = new UserExtra();
            $userExtra->user_id = $this->user->id;
            $userExtra->save();
        }

        return UserExtra::where('user_id', $this->user->id)->first()->toArray();
    }

    //黑名单列表
    public function getBlackList($offset, $limit)
    {
        $list = (new BlackList())->setTable('b')->from('black_lists as b')
            ->join('users as u', 'u.id', '=', 'b.target_id')
            ->where('b.user_id', $this->user->id)
            ->where('b.status', 0)//0加入黑名单，1移除
            ->select('u.id', 'name', 'avatar', 'is_auth')
            ->orderBy('b.updated_at', 'desc')
            ->offset($offset)
            ->limit($limit)
            ->get();

        if($list->isEmpty()){
            return [];
        }
        $list = $list->toArray();
        foreach ($list as $key => &$val) {
            $val['have_user_course'] = UserService::haveUserCourse($val['id']);
        }
        return $list;
    }

    //关注或取消关注
    public function followAction($target_id)
    {
        DB::beginTransaction();
        try {
            if ($this->user->id == $target_id) {
                throw new Exception(trans('api.ILLEGAL_OPERATION'));
            }
            if (!$res = User::query()->where(['id' => $target_id])->whereNull('deleted_at')->first()) {
                throw new Exception(trans('api.NOT_EXIST'));
            }
            $map = ['user_id' => $this->user->id, 'target_id' => $target_id];

            //首先判断是否为好友
            $flag1 = self::isFriends($this->user->id, $target_id);

            if (!$record = UserFollow::query()->where($map)->first()) {
                $map['status'] = 1;
                $map['created_at'] = $map['updated_at'] = Carbon::now();
                UserFollow::query()->insert($map);
                //我的 关注数 加 1
                UserExtra::query()->where('user_id', $this->user->id)->increment('follow_count');
                //被关注人 粉丝 加 1
                UserExtra::query()->where('user_id', $target_id)->increment('fans_count');

                //给用户添加消息记录
                $notice = NoticeService::getInstance();
                $notice->send_msg($target_id, '', 10, $this->user->id, 'api.FOLLOW', 0);

            } else {
                $status = $record->status ? 0 : 1;
                UserFollow::query()->where($map)->update(['status' => $status, 'updated_at' => Carbon::now()]);
                if (!$status) {
                    UserExtra::query()->where('user_id', $this->user->id)->decrement('follow_count');
                    UserExtra::query()->where('user_id', $target_id)->decrement('fans_count');
                } else {
                    UserExtra::query()->where('user_id', $this->user->id)->increment('follow_count');
                    UserExtra::query()->where('user_id', $target_id)->increment('fans_count');
                    //给用户添加消息记录
                    $notice = NoticeService::getInstance();
                    $notice->send_msg($target_id, '', 10, $this->user->id, 'api.FOLLOW', 0);
                }
            }
            //再次判断是否为好友
            $flag2 = self::isFriends($this->user->id, $target_id);

            //如果原来是好友，现在不是，则各自减一
            if ($flag1 && !$flag2) {
                self::decFriendsCount($this->user->id, $target_id);
            }
            //如果原来不是好友，现在是，则各自加一
            if (!$flag1 && $flag2) {
                self::incFriendsCount($this->user->id, $target_id);
            }

            DB::commit();
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            return $e->getMessage();
        }
    }

    //判断是否为好友
    private static function isFriends($user_id, $target_id)
    {
        $map1 = ['user_id' => $user_id, 'target_id' => $target_id, 'status' => 1];
        $map2 = ['user_id' => $target_id, 'target_id' => $user_id, 'status' => 1];

        $res1 = UserFollow::query()->where($map1)->first();
        $res2 = UserFollow::query()->where($map2)->first();

        if (!empty($res1) && !empty($res2)) { //是好友
            return true;
        }

        return false;
    }

    public static function decFriendsCount($user_id, $target_id)
    {
        UserExtra::query()->whereIn('user_id', [$user_id, $target_id])->decrement('friends_count');
    }

    public static function incFriendsCount($user_id, $target_id)
    {
        UserExtra::query()->whereIn('user_id', [$user_id, $target_id])->increment('friends_count');
    }

    //我关注的
    public function getMylikeUsers($userId)
    {
        $list = UserFollow::query()
            ->join('users', 'users.id', '=', 'user_follows.target_id')
            ->where('user_follows.user_id', $userId)
            ->where('user_follows.status', 1)
            ->select('users.id', 'name', 'avatar', 'is_auth')
            ->orderBy('user_follows.updated_at', 'desc')
            ->get();

        if($list->isEmpty()){
            return [];
        }
        $list = $list->toArray();
        foreach ($list as $key => &$val) {
            $val['have_user_course'] = UserService::haveUserCourse($val['id']);
        }
        return $list;
    }

    //我的粉丝
    public function getMyFans($userId)
    {
        //关注我的
        $list = UserFollow::query()
            ->join('users', 'users.id', '=', 'user_follows.user_id')
            ->where('user_follows.target_id', $userId)
            ->where('user_follows.status', 1)//0取消关注，1关注
            ->select('users.id', 'name', 'sex', 'avatar', 'is_auth')
            ->orderBy('user_follows.updated_at', 'desc')
            ->get();

        if($list->isEmpty()){
            return [];
        }
        $list = $list->toArray();
        //我关注的用户 $user_ids
        $user_ids = UserFollow::query()
            ->where('user_id', $userId)
            ->where('status', 1)
            ->pluck('target_id')
            ->toArray();

        //把互相关注的用户标记下
        foreach ($list as $key => $val) {
            $val['is_friends'] = 0;
            $val['have_user_course'] = UserService::haveUserCourse($val['id']);
            if (in_array($val['id'], $user_ids)) {
                $val['is_friends'] = 1;
            }
            $list[$key] = $val;
        }

        MessageService::changeStatus($this->user->id, [10]);

        return $list;
    }

    //我的好友（互相关注的人）
    public function getMyFriends($userId, $keyword = '')
    {
        //获取我关注的
        $targetIds = UserFollow::query()->where(['user_id' => $userId, 'status' => 1])->pluck('target_id');
        $targetIds = !empty($targetIds) ? $targetIds->toArray() : [];

        //获取关注我的
        $userIds = UserFollow::query()->where(['target_id' => $userId, 'status' => 1])->pluck('user_id');
        $userIds = !empty($userIds) ? $userIds->toArray() : [];

        //取交集便是好友
        $friendsIds = array_intersect($targetIds, $userIds);

        $list = User::query()
            ->whereIn('id', $friendsIds)
            ->when($keyword, function ($query, $keyword) {
                return $query->where('name', 'like', $keyword . '%')->orWhere('id', $keyword);
            })
            ->select('id', 'name', 'sex', 'avatar', 'is_auth')
            ->orderBy('id', 'desc')
            ->get();

        if($list->isEmpty()){
            return [];
        }
        $list = $list->toArray();
        foreach ($list as $key => &$val) {
            $val['have_user_course'] = UserService::haveUserCourse($val['id']);
        }

        return $list;
    }

    //修改个人资料信息
    public function updateUserInfo($request, $id)
    {
        $user = User::find($id);

        $beforeName = $user->name;
        $beforeAvatar = $user->avatar;

        if (isset($request->name) && !empty($request->name)) {
            $user->name = $request->name;
        }
        if (isset($request->bio) && !empty($request->bio)) {
            $user->bio = $request->bio;
        }
        if (isset($request->sex) && !empty($request->sex)) {
            $user->sex = $request->sex;
        }
        if (isset($request->birthday) && !empty($request->birthday)) {
            $user->birthday = $request->birthday;
        }
        if (isset($request->bg) && !empty($request->bg)) {
            $user->bg = $request->bg;
        }
        if (isset($request->avatar) && !empty($request->avatar)) {
            $user->avatar = $request->avatar;
        }
        if (isset($request->remark) && !empty($request->remark)) {
            $user->remark = $request->remark;
        }
        if (isset($request->usga) && !empty($request->usga)) {
            $user->usga = $request->usga;
        }
        if (isset($request->ball_age) && !empty($request->ball_age)) {
            $user->ball_age = $request->ball_age;
        }

        if (!$user->save()) {
            throw new Exception(trans('api.DATA_SAVE_FALSE'));
        }

        if ((isset($request->avatar) && ($beforeAvatar != $request->avatar)) || (isset($request->name) && ($beforeName != $request->name))) {
            //更新用户聊天头像或昵称
            $tencentImAccount = new TencentImAccountService();
            $tencentImAccount->changeInfo($user);
        }

        //如果用户更新了头像
        if (isset($request->avatar) && ($beforeAvatar != $request->avatar)) {
            //更新用户所在群的群聊头像
            $tencentImGroup = new TencentImGroupService();
            $myGroups = $tencentImGroup->getJoinedGroupList($user);
            if (!empty($myGroups)) {
                foreach ($myGroups['GroupIdList'] as $key => $val) {
                    if (isset($val['GroupId']) && !empty($val['GroupId'])) {
                        $tencentImGroup->updateFaceUrl($val['GroupId']);
                    }
                }
            }
        }

        return true;
    }

    //用户认证
    public function identify($request)
    {
        $userIdentify = new UserIdentify();

        $info = $userIdentify
            ->where('user_id', $this->user->id)
            ->whereIn('status', [0, 1])
            ->first();

        if ($info) {
            throw new Exception(trans('api.HAD_SUBMIT'));
        }

        $userIdentify->user_id = $this->user->id;
        $userIdentify->name = $request->name;
        $userIdentify->sex = $request->sex;
        $userIdentify->mobile = $request->mobile;
        $userIdentify->birthday = $request->birthday;
        $userIdentify->avatar = $request->avatar;
        $userIdentify->bio = $request->bio;
        $userIdentify->type = $request->type; //认证类型：1-组织，2-个人
        $userIdentify->status = 0; //0未认证
        $userIdentify->action_type = 2; //1后台添加，2用户申请

        if (!$userIdentify->save()) {
            throw new Exception(trans('api.DATA_SAVE_FALSE'));
        }

        return true;
    }

    //国际区号
    public function getMobilePrefixList()
    {
        $mobilePrefixList = Redis::get('mobile_prefix_list');

        if (empty($mobilePrefixList)) {
            $mobilePrefixList = MobilePrefix::query()->select('zh_country', 'en_country', 'prefix')->get()->toArray();
            $mobilePrefixList = json_encode($mobilePrefixList);
            Redis::setex('mobile_prefix_list', 30 * 24 * 3600, $mobilePrefixList);
        }

        $mobilePrefixList = json_decode($mobilePrefixList, true);

        $SortService = new SortService();
        $en_list = $SortService->groupByFirstLetterEn($mobilePrefixList);
        $zh_list = $SortService->groupByFirstLetterZh($mobilePrefixList);

        $data = [
            'en' => $en_list,
            'zh' => $zh_list,
        ];

        return $data;
    }

    //用户积分变化
    public function changeIntegral($userId, $amount=0, $type=1)
    {
        DB::beginTransaction();
        try{
            if($type == '+'){
                UserExtra::query()->where('user_id', $userId)->increment('integral', $amount);
            }else{
                UserExtra::query()->where('user_id', $userId)->decrement('integral', $amount);
            }

            $nowIntegral = UserIntegral::query('user_id', $user_id)->orderByDesc('id')->value('integral');

            $userIntegral = App::make('UserIntegral');
            $userIntegral->user_id = $userId;
            $userIntegral->type = $type;
            $userIntegral->before_integral = $nowIntegral;
            $userIntegral->amount = $amount;
            $userIntegral->after_integral = $nowIntegral + $amount;
            $userIntegral->save();

            DB::commit();
        }catch (Exception $exception){
            ErrorMsgServive::write($exception, request()->url());
            DB::rollBack();
        }
    }

}
