<?php


namespace App\Modules\User\Services;

use App\Cache\Lock\LockCache;
use App\Consts\ErrorConst;
use App\Consts\QuickConst;
use App\Jobs\Push\NewUserPushMsgDelay;
use App\Jobs\QappTikTok\QappTikTokUserRequest;
use App\Jobs\QappTikTok\QappTikTokUser;
use App\Libs\Utils;
use App\Modules\Report\Services\ReportService;
use App\Modules\User\Models\QappPackage;
use App\Modules\User\Models\QappUser;
use App\Modules\User\Models\User;
use App\Modules\UserTask\Services\BaseTask;
use App\Modules\UserTask\Services\UserTaskService;
use Exception;
use Illuminate\Support\Facades\DB;
use Tymon\JWTAuth\Facades\JWTAuth;

/**
 *
 */
class QappUserService
{
    /**
     * 登录
     */
    public function login(array $data)
    {
        $codeVersion   = getProp($data, 'codeVersion');
        $lockToken     = '';
        $isNewRegister = false;
        $device_no     = $data['device_no'];
        $channel_id    = $this->findChannelId($data['package']);
        $qapp_user     = $this->getQAppUserByDeviceNo($device_no, $channel_id);
        if (!$qapp_user) {
            // 判断版本号，大于等于1.0.0才做处理
            if (version_compare($codeVersion, '1.0.0', '>=')) {
                // 加锁3秒，否则报错
                $lockToken = md5($device_no . ':' . $channel_id);
                $lock      = LockCache::getLock($lockToken, 3);
                if (!$lock) {
                    Utils::throwError(ErrorConst::QAPP_LOGIN_FREQUENTLY);
                }
            }

            myLog('login')->info('register', compact('codeVersion', 'device_no', 'channel_id', 'lockToken'));

            // 初始化新用户
            $isNewRegister = true;
            $qapp_user     = $this->createQuickAppUser($data);
        }
        if ($qapp_user) {
            $user  = $qapp_user->user;
            $uid   = $user->id;
            $time  = strtotime("+1 month");
            $token = JWTAuth::fromUser($user);
            if ($data['send_order_id']) {
                UserService::setUserSendOrder((int)$uid, (int)$data['send_order_id']);
            }
            // 新注册统计
            if ($isNewRegister && $qapp_user) {
                // 注册统计
                QappAddDeskTopService::incrAddDeskTop($uid, QuickConst::FIELD_REGISTER);
            }
            return compact('token', 'time', 'uid');
        } else {
            return [];
        }
    }

    public function getGolableUser()
    {
        $qapp_user = app()->make('qapp_user');
        return $qapp_user;
    }

    /**
     * 绑定手机号
     * 多个账号可以绑定一个手机号
     */
    public function bindPhone(int $uid, string $phone, string $version = "1.0")
    {
        $qapp_user = QappUser::where('uid', $uid)->first();
        if ($qapp_user->phone && $qapp_user->phone != $phone) {
            return false;
        } else {
            try {
                DB::beginTransaction();
                if (!$qapp_user->phone) {
                    $reward = 100;
                    if ($version == "1.0") {
                        User::where('id', $uid)->update(
                            [
                                'balance'        => DB::raw('balance+' . $reward),
                                'reward_balance' => DB::raw('reward_balance+' . $reward)
                            ]
                        );
                    } else {
                        UserTaskService::addUserTaskQueue($uid, BaseTask::bind_phone, UserTaskService::add_trigger);
                    }
                }
                $qapp_user->phone = $phone;
                $qapp_user->save();
                DB::commit();
            } catch (Exception $e) {
                myLog('bindPhone')->error($e->getMessage());
            }
            return true;
        }
    }

    public function setGolableUser(int $uid, string $package)
    {
        $user_info                     = $this->getQAppUserByUid($uid, $package);
        $qapp_user                     = app()->make('qapp_user');
        $qapp_user->id                 = $user_info->id;
        $qapp_user->uid                = $user_info->uid;
        $qapp_user->send_order_id      = $user_info->send_order_id;
        $qapp_user->device_no          = $user_info->device_no;
        $qapp_user->device_info        = $user_info->device_info;
        $qapp_user->phone              = $user_info->phone;
        $qapp_user->user               = $user_info->user;
        $qapp_user->app_pay_merchat_id = $user_info->app_pay_merchat_id;
        $qapp_user->h5_pay_merchat_id  = $user_info->h5_pay_merchat_id;
        $qapp_user->ali_pay_merchat_id = $user_info->ali_pay_merchat_id;
    }

    /**
     * 根据设备号获取快应用用户信息
     */
    public function getQAppUserByDeviceNo(string $device_no, int $channel_id)
    {
        $qapp_user = QappUser::where('device_no', $device_no)->where('channel_id', $channel_id)->first();
        if ($qapp_user) {
            $user            = User::find($qapp_user->uid);
            $qapp_user->user = $user;
        }
        return $qapp_user;
    }

    /**
     * 根据uid获取快应用用户信息
     * @param int    $uid
     * @param string $package
     * @return mixed
     */
    public function getQAppUserByUid(int $uid, string $package = '')
    {
        $qapp_user = QappUser::where('uid', $uid)->first();
        if ($qapp_user) {
            $user                     = User::find($uid);
            $qapp_user->user          = $user;
            $qapp_user->send_order_id = UserService::getUserSendOrder($uid);

            // 针对聚裕的包无法支付的问题（注册时传入了仙女阅读的包名，导致支付时取的支付信息不一致）
            if ($package && $package === 'com.juyu.kuaiying.rmyq') {
                $package_info = QappPackage::where('package', $package)->first();
            } else {
                $package_info = QappPackage::where('channel_id', $user->distribution_channel_id)->first();
            }

            // 支付id
            $qapp_user->app_pay_merchat_id = $package_info->app_pay_merchat_id;
            $qapp_user->h5_pay_merchat_id  = $package_info->h5_pay_merchat_id;
            $qapp_user->ali_pay_merchat_id = $package_info->ali_pay_merchat_id;
        }
        return $qapp_user;
    }


    /**
     * 创建快应用用户信息
     */
    public function createQuickAppUser(array $data)
    {
        try {
            DB::beginTransaction();
            $user            = $this->createUser($data);
            $channel_id      = $user->distribution_channel_id;
            $qapp_user       = QappUser::firstOrCreate([
                'device_no'  => $data['device_no'],
                'channel_id' => $channel_id,
            ], [
                'imei'        => $data['imei'],
                'androidid'   => $data['androidid'],
                'mac'         => $data['mac'],
                'uid'         => $user->id,
                'device_info' => $data['device_info'],
            ]);
            $qapp_user->user = $user;
            DB::commit();

            $this->syncHandle($user, $data);

            return $qapp_user;
        } catch (Exception $e) {
            myLog('create_user')->error($e->getMessage());
        }
    }

    /**
     * 新用户异步处理数据
     */
    private function syncHandle(User $user, array $data)
    {
        // 队列处理回传业务
        $tikTokRegisterRequest                = new QappTikTokUserRequest();
        $tikTokRegisterRequest->ip            = $user->register_ip;
        $tikTokRegisterRequest->device_no     = $data['device_no'];
        $tikTokRegisterRequest->mac           = $data['mac'];
        $tikTokRegisterRequest->channel_id    = $user->distribution_channel_id;
        $tikTokRegisterRequest->uid           = $user->id;
        $tikTokRegisterRequest->register_time = $user->created_at->format('Y-m-d H:i:s');
        $tikTokRegisterRequest->send_order_id = $data['send_order_id'];
        myLog('qapp_register')->info('', compact('tikTokRegisterRequest'));

        // 回传业务
        $job = new QappTikTokUser($tikTokRegisterRequest);
        dispatch($job->onConnection('rabbitmq')->onQueue('qapp_tiktok_user_register_queue'));

        UserTaskService::addUserTaskQueue($user->id, BaseTask::register, UserTaskService::add_trigger);

        $job = new NewUserPushMsgDelay($user->id);
        dispatch($job->onConnection('rabbitmq')->onQueue('new_user_push_msg'));

        // 同步数据
        $user->channel_id = $user->distribution_channel_id;
        ReportService::reportRegister($user);
    }

    private function findChannelId(string $package)
    {
        $channel_id = env('QUICKAPP_SITE');
        if ($package) {
            $package_info = QappPackage::where('package', $package)->first();
            $channel_id   = $package_info ? $package_info->channel_id : $channel_id;
        }
        return $channel_id;
    }

    /**
     * 创建用户
     */
    private function createUser(array $data): User
    {
        $openid                  = $data['device_no'];
        $unionid                 = $data['device_no'];
        $register_ip             = _getIp();
        $distribution_channel_id = $this->findChannelId($data['package']);
        $send_order_id           = $data['send_order_id'];
        $unique_key              = compact('unionid', 'distribution_channel_id');
        $data                    = compact('openid', 'register_ip', 'send_order_id');
        return User::firstOrCreate($unique_key, $data);
    }
}
