<?php


namespace App\Http\Controllers\V1;

use App\Http\Requests\UpdateUser;
use App\Models\SystemAvatar;
use App\Models\User;
use App\Models\BlackList;
use App\Models\UserFeedback;
use App\Models\UserIdentify;
use App\Models\EmailCode;
use App\Repositories\UserRepositorie;
use App\Services\Api\UserService;
use App\Services\Api\GameService;
use App\Services\SmsServer;
use App\Services\JPushService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Validator;
use Laravel\Socialite\Facades\Socialite;
use PHPUnit\Util\Exception;

class UserController extends Controller
{
    protected $UserService;
    protected $GameService;

    public function __construct()
    {
        parent::__construct();
        $this->UserService = new UserService();
        $this->GameService = new GameService();
        $this->user = auth('api')->user();
        if (!empty($this->user->deleted_at)) {
            JPushService::updateAlias($this->user->jpush_reg_id, '');
            $this->user->online = 0;
            $this->user->save();
            auth('api')->logout();
        }
    }

    //个人中心
    public function userinfo()
    {
        $user = UserService::getUserInfo($this->user->id);

        $extra = $this->UserService->userExtra();
        $user['friends_count'] = $extra['friends_count']; //好友数
        $user['fans_count'] = $extra['fans_count']; //粉丝数
        $user['follow_count'] = $extra['follow_count']; //关注数
        $user['team_count'] = $this->UserService->teamCount(); //球队数
        $user['game_count'] = $this->UserService->totalGames(); //总场次
        $user['history_courses_count'] = $this->UserService->historyCourses(); //打过的球场数

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

        return $this->success($user);
    }

    //修改手机号
    public function updateMobile(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'mobile' => 'bail|required',
            'smsCode' => 'bail|required',
        ], [
            'mobile.required_without' => trans('api.PLEASE_ENTER_MOBILE_PHONE_NUMBER'),
            'mobile.regex' => trans('api.MOBILE_PHONE_NUMBER_FORMAT_ERROR'),
            'smsCode.required' => trans('api.VERIFICATION_CODE_NOT_NULL'),
        ]);

        try {
            if ($validator->fails()) {
                throw new Exception($validator->messages()->first());
            }
            if (User::where('mobile', $request->mobile)->first()) {
                throw new Exception(trans('api.MOBILE_HAD_EXIST'));
            }
            $user = User::find($this->user->id);
            //手机验证码验证
            SmsServer::checkSmsCodeByVerifyKey($request->verifyKey, $request->smsCode);

            $user->mobile = $request->mobile;
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //修改密码
    public function updatePassword(Request $request)
    {
        try {
            $user = User::find($this->user->id);
            $account = $user->mobile ? $user->mobile : $user->email;
            if (!self::isPasswordRight($account, $request->old_password)) {
                throw new Exception(trans('api.PASSWORD_ERROR'));
            }
            $user->password = $request->new_password;
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //修改个人背景图
    public function background(Request $request)
    {
        try {
            $user = User::find($this->user->id);
            $user->bg = $request->bg;
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //绑定或解绑 手机
    public function bindMobile(Request $request)
    {
        try {
            if(!$this->isAllowUnbound()){
                throw new Exception(trans('api.NOT_ALLOW'));
            }
            $user = User::find($this->user->id);

            if (!empty($user->mobile)) { //要解绑
//                if (!empty($user->email)) { //允许解绑
//                    $user->mobile = '';
//                } else {
//                    throw new Exception(trans('api.EMAIL_NO_BIND'));
//                }
                $user->mobile = '';
            } else { //要绑定
                $user->mobile = $request->mobile;
            }
            SmsServer::checkSmsCodeByVerifyKey($request->verifyKey, $request->smsCode);
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //绑定或解绑 邮箱
    public function bindEmail(Request $request)
    {
        try {
            if(!$this->isAllowUnbound()){
                throw new Exception(trans('api.NOT_ALLOW'));
            }
            $user = User::find($this->user->id);

            if (!empty($user->email)) { //要解绑
                $user->email = '';
            } else { //要绑定
                $user->email = $request->email;
            }
            if (!self::isEmailCodeRight($request->email, $request->code)) {
                throw new Exception(trans('api.VERIFY_CODE_FALSE'));
            }
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //绑定或解绑 微信
    public function bindWx()
    {
        try {
            if(!$this->isAllowUnbound()){
                throw new Exception(trans('api.NOT_ALLOW'));
            }
            $user = User::find($this->user->id);
            if (!empty($user->wx_openid)) { //要解绑
                $user->wx_openid = '';
            } else { //要绑定
                $githubUser = Socialite::driver('weixin')->stateless()->user();
                $user->wx_openid = $githubUser->getId();
            }
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //绑定或解绑 facebook
    public function bindFacebook(Request $request)
    {
        try {
            if(!$this->isAllowUnbound()){
                throw new Exception(trans('api.NOT_ALLOW'));
            }
            $token = $request->token;
            $user = User::find($this->user->id);
            $result = Http::get('https://graph.facebook.com/me', ['access_token'=>$token])->throw()->json();

            if (!empty($user->fb_openid)) { //要解绑
                $user->fb_openid = '';
            } else { //要绑定
                $user->fb_openid = isset($result['id']) ? $result['id'] : '';
            }
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //绑定或解绑 苹果账号
    public function bindApple(Request $request)
    {
        try {
            if(!$this->isAllowUnbound()){
                throw new Exception(trans('api.NOT_ALLOW'));
            }
            $user = User::find($this->user->id);

            if (!empty($user->apple_openid)) { //要解绑
                $user->apple_openid = '';
            } else { //要绑定
                $user->apple_openid = $request->apple_openid;
            }
            if (!$user->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //判断是否允许解绑
    public function isAllowUnbound()
    {
         $user = $this->user;
         if(empty($user->mobile) && empty($user->email) && empty($user->wx_openid) && empty($user->fb_openid) && empty($user->apple_openid)){
             return false;
         }
         return true;
    }

    //加入或移除 黑名单
    public function black(Request $request)
    {
        try {
            $user_id = $this->user->id;
            $target_id = $request->target_id;
            if ($user_id == $target_id) {
                throw new Exception(trans('api.ILLEGAL_OPERATION'));
            }
            $record = BlackList::query()->where(['user_id' => $user_id, 'target_id' => $target_id])->first();
            if (!$record) {
                $record = new BlackList();
                $record->user_id = $user_id;
                $record->target_id = $target_id;
                $record->status = 0; //0已拉黑，1正常
            } else {
                $record->status = $record->status ? 0 : 1;
            }
            if (!$record->save()) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            }
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //黑名单列表
    public function blackList(Request $request)
    {
        $limit = $request->query('limit', 15);
        $offset = $request->query('offset', 0);

        $list = $this->UserService->getBlackList($offset, $limit);

        return $this->success($list);
    }

    //我关注的
    public function myLikeUsers(Request $request)
    {
        $userId = $request->input('user_id', 0);
        $list = $this->UserService->getMylikeUsers($userId);

        return $this->success($list);
    }

    //我的粉丝
    public function myFans(Request $request)
    {
        $userId = $request->input('user_id', 0);
        $list = $this->UserService->getMyFans($userId);

        return $this->success($list);
    }

    //关注或取消关注
    public function follow(Request $request)
    {
        try {
            if ($this->user->id == $request->target_id) {
                throw new Exception(trans('api.ILLEGAL_OPERATION'));
            }
            if (!$this->UserService->followAction($request->target_id)) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            };
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //判断邮箱验证码
    protected function isEmailCodeRight($email, $code)
    {
        $result = EmailCode::where('channel', 'email')
            ->where('account', $email)
            ->where('code', $code)
            ->where('state', 0)
            ->orderBy('id', 'desc')
            ->first();
        if (!$result) {
            return false;
        }
        $verify = EmailCode::find($result->id);
        $verify->state = 1; //验证通过就失效
        $verify->save();

        return true;
    }

    //判断密码是否正确
    protected function isPasswordRight($account, $password)
    {
        $credentials1 = ['mobile' => $account, 'password' => $password];
        $credentials2 = ['email' => $account, 'password' => $password];
        if (!auth('api')->attempt($credentials1) && !auth('api')->attempt($credentials2)) {
            return false;
        }
        return true;
    }

    //我的好友
    public function myFriends(Request $request)
    {
        $userId = $request->input('user_id', 0);
        $keyword = $request->input('keyword', '');
        $list = $this->UserService->getMyFriends($userId, $keyword);

        return $this->success($list);
    }

    //好友操作 status：0 申请中，1好友，2已拉黑，3已删除
    public function handleFriend(Request $request)
    {
        try {
            if ($this->user->id == $request->target_id) {
                throw new Exception(trans('api.ILLEGAL_OPERATION'));
            }
            if (!$this->UserService->handleFriend($request->target_id, $request->status)) {
                throw new Exception(trans('api.DATA_SAVE_FALSE'));
            };
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //修改个人信息
    public function updateUserInfo(UpdateUser $request)
    {
        try {
            $this->UserService->updateUserInfo($request, $this->user->id);
        } catch (\Exception $exception) {
            Log::error($exception->getMessage());
            return $this->error($exception->getMessage());
        }

        return $this->success();
    }

    //用户认证
    public function identify(Request $request)
    {
        try {
            $this->UserService->identify($request, $this->user->id);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        return $this->success();
    }

    //用户认证状态
    public function identifyStatus()
    {
        $info = UserIdentify::where('user_id', $this->user->id)->select('id', 'status', 'type')->orderBy('id', 'desc')->first();

        $status = !empty($info) ? $info['status'] : -1;
        $type = !empty($info) ? $info['type'] : 0;
        $data = [
            'status' => $status,
            'type' => $type,
        ];
        return $this->success($data);
    }

    //统头像库 如果后台更新，会删除缓存
    public function systemAvatar()
    {
        $maleList = SystemAvatar::where('sex', 1)->select('id', 'img', 'sex')->orderByDesc('id')->get()->toArray();
        $femaleList = SystemAvatar::where('sex', 2)->select('id', 'img', 'sex')->orderByDesc('id')->get()->toArray();
        $avatarList = [
            'male' => trans('api.MALE'),
            'male_list' => $maleList,
            'female' => trans('api.FEMALE'),
            'female_list' => $femaleList,
        ];

        return $this->success($avatarList);
    }

    //国际区号 手机号前缀
    public function mobilePrefix()
    {
        $list = $this->UserService->getMobilePrefixList();

        return $this->success($list);
    }

    /**
     * 问题反馈
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function feedback(Request $request)
    {
        try {
            $content = $request->post('content');
            $file_url = $request->post('file_url');
            $user = auth('api')->user();
            $feedback = new UserFeedback();
            $feedback->user_id = $user->id;
            $feedback->content = $content;
            $feedback->file = !empty($file_url) ? json_encode($file_url) : '';
            $feedback->save();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
        return $this->success();
    }

    //注销账号
    public function delAccount()
    {
        try {
            $user = User::find($this->user->id);

            $user->email = $user->email ? '0' . $user->email : '';
            $user->mobile = $user->mobile ? '0' . $user->mobile : '';
            $user->wx_openid = '';
            $user->fb_openid = '';
            $user->apple_openid = '';
            $user->status = 0;
            $user->online = 0;
            $user->jpush_reg_id = '';
            $user->tencent_im_user_id = '';
            $user->deleted_at = date('Y-m-d H:i:s');
            $user->save();

            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }

    }

    //切换声音 极光推送声音
    public function chooseJpushVoice(Request $request)
    {
        $user = User::find($this->user->id);
        $user->jpush_voice = $request->input('voice', '');
        $user->save();

        return $this->success();
    }

}
