<?php

namespace App\Http\Middleware;

use App\Modules\Book\Services\BookConfigService;
use App\Modules\Channel\Models\YqMoveChannel;
use App\Modules\Channel\Services\ChannelService;
use App\Modules\OfficialAccount\Services\ForceSubscribeService;
use App\Modules\SendOrder\Services\SendOrderService;
use App\Modules\Statistic\Services\WapVisitStatService;
use App\Modules\User\Models\YqMove;
use App\Modules\User\Services\ReadRecordService;
use App\Modules\User\Services\UserService;
use App\Modules\YunQi\Services\BookUserService;
use App\Modules\YunQi\Services\YqUserBidRelationService;
use App\Modules\YunQi\Services\YqZsyTestService;
use Closure;
use Cookie;
use App\Libs\ApiClient;
use EasyWeChat\Core\Exception;
use Illuminate\Http\Request;
use Log;
use Redis;
use App\Modules\OfficialAccount\Services\OfficialAccountService;
use Hashids;
use GuzzleHttp\Client;
use App\Jobs\SendTexts;
use DB;
use EasyWeChat\Foundation\Application;

class ReadOauth
{
    /**
     * 判断是否登陆.
     */
    public function handle(Request $request, Closure $next)
    {
        $this->cookieNoCrypt();
        $test = 0;
        if ($request->has('test') && $request->input('test') == 'bonan') {
            $test = 1;
        }

        $uid_cookie = Cookie::get(env('COOKIE_AUTH_WEB_WECHAT'));
        if (!$uid_cookie) $uid_cookie = $this->authCallBack($request);

        $h5_scheme = env('H5_SCHEME', 'https');
        $params = $request->except('_url');
        $url = str_replace('http://', $h5_scheme . '://', url()->current() . '?' . http_build_query($params));
        //Log::info('-----------------uid' . $uid_cookie);
        $send_order_id = $request->input('send_order_id');
        if ($send_order_id) {
            Cookie::queue('send_order_id', $send_order_id, env('U_COOKIE_EXPIRE'), null, null, false, false);
        }
        $distribution_channel_id = str_replace('site', '', explode('.', _domain())[0]);
        $origin_distribution_channel_id = $distribution_channel_id;
        if (!is_numeric($distribution_channel_id)) {
            $distribution_channel_id = decodeDistributionChannelId($distribution_channel_id);
        }
        if (!$distribution_channel_id) {
            return response()->error('WAP_SYS_ERROR');
        }
        //禁止访问的site
        $not_allow_access_site = env('NOT_ALLOW_ACCESS_SITE', '');
        if ($not_allow_access_site) {
            $not_allow_access_site_arr = explode(',', $not_allow_access_site);
            if (in_array($distribution_channel_id, $not_allow_access_site_arr)) {
                return response($this->notAccessPage())->header('Content-Type', 'text/html');
            }
        }
        $uri_send_order_id = 0;
        $uri = $request->input('_url');
        if (strpos($uri, '/yun/') !== false) {
            $uri_send_order_id = (int)str_ireplace('/yun/', '', $uri);
        }
        $yun = $request->get('yun');
        $yun && $uri_send_order_id = $yun;
        if (!$uid_cookie && $test == 0) {
            if ($uri_send_order_id) {
                Cookie::queue('send_order_id', $uri_send_order_id, env('U_COOKIE_EXPIRE'), null, null, false, false);
            }
            $this->share($request);
            $old_auth = false;
            if ($old_auth && !in_array($distribution_channel_id, explode(',', env('NEW_AUTH_CHANNEL_ID', 1)))) {
                //旧的授权
                Cookie::queue('auth_redirect', urlencode($url), env('U_COOKIE_EXPIRE'));
                $auth_v2_url = $this->authV2($request, $distribution_channel_id);
                if ($auth_v2_url) {
                    return redirect()->to($auth_v2_url);
                }
                $redirect_V2 = $this->auth($request, $distribution_channel_id);
                if ($redirect_V2) {
                    return redirect()->to($redirect_V2);
                }
            } else {
                //新的授权
                $options = $this->authReduceRedirect($request,$distribution_channel_id,$uri_send_order_id);
                $app = new Application($options);
                //Log::info($options);
                return $app->oauth->redirect();
            }
        }

        //个性化推送
        $this->stylePush($request, $uid_cookie, $distribution_channel_id);

        //禁止明文访问
        if ($this->isForbidPrimaryNumberChannleID($origin_distribution_channel_id, $uid_cookie)) {
            return response('<html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>该网站地址暂停访问</title></head><body style="padding:0;margin:0;font-size:0"><div style="width:300px;height:100px;margin: 20px auto"><p style="font-size:20px;color:red;text-align:center">该网站地址暂停访问，请联系客服微信获取新地址：wuxinchao12</p></body></html>');
        }
        if ($request->has('appid') && $request->has('openid')) {
            Log::info('param is:');
            Log::info($params);
            $uri = $request->input('_url');
            $openid = $request->get('openid');
            $appid = $request->get('appid');
            /* $user_info = ForceSubscribeService::getUserInfo($appid,$openid);
             Log::info('appid user id to userinfo');
             Log::info($user_info);*/
            $back = $request->get('back', '');
            if ($openid && $appid && $distribution_channel_id && $uid_cookie) {
                $this->apidAndOpenId($distribution_channel_id, $appid, $openid, $uid_cookie, $uri_send_order_id);
                $channel = ChannelService::getById($distribution_channel_id);
                $is_yq_move = $this->isQyMove($channel, $distribution_channel_id);
                if ($is_yq_move) {
                    $move_user = YqMove::where('zsy_uid', $uid_cookie)->select('zsy_uid')->first();
                    if (!$move_user) {
                        if (!$back) {
                            $yq_home = $this->getYqChannleIdByAppid($appid);
                            Log::info('$this->getYqChannleIdByAppid($appid) is : ');
                            Log::info($yq_home);
                            if ($yq_home) {
                                $params['zsy_channel_id'] = encodeDistributionChannelId($distribution_channel_id);
                                $params['pa'] = $uri;
                                $back_url = $yq_home . 'move?' . http_build_query($params);
                                Log::info('$yq_home - $back_url is: ' . $back_url);
                                return redirect()->to($back_url);
                            }
                        }
                        $this->moveUserFromYq($distribution_channel_id, $appid, $openid, $uid_cookie);
                    }
                }
            }
        }
        /*//云栖测试
        $qy_test_url = $this->yqTest($request,$uid_cookie,$distribution_channel_id);
        if($qy_test_url){
            //Log::info('url is: '.$qy_test_url);
            return redirect()->to($qy_test_url);
        }*/
        $this->yun($request, $uid_cookie, $distribution_channel_id);
        //只能推送的统计
        $this->smartPush($request, $uid_cookie);
        //数据分析 长篇推短片的统计
        $this->dataAnalysis($request, $uid_cookie);
        //from where的临时统计
        $this->tempFromWhere($request, $uid_cookie);
        //统计访问site数字的uid记录下
        //$this->recordPrimaryNumberChannleIDUser($origin_distribution_channel_id,$uid_cookie);
        $response = $next($request);
        $stats = $request->get('stats', 0);
        if ($request->has('fromtype') && $request->input('fromtype')) {
            try {
                $from = $request->input('fromtype', 'main');
                Cookie::queue('from', $from, env('U_COOKIE_EXPIRE'), null, null, false, false);
                if (!$stats) {
                    Redis::sadd('push:distribution_channel_id:' . $distribution_channel_id . 'from:' . $from . ':date:' . date('Y-m-d'), $uid_cookie);
                    Redis::sadd('push:distribution_channel_id:alluv:from:' . $from, $uid_cookie);

                    Redis::hincrby('push:distribution_channel_id:allpv', $from, 1);

                    Redis::hincrby('customer:push:click:distribution_channel_id:' . $distribution_channel_id . 'from:' . $from, date('Y-m-d'), 1);
                    Redis::sadd('wap_from_stats' . date('Y-m-d'), $distribution_channel_id . '-' . $from);
                }
            } catch (\Exception $e) {
                Log::info($e);
            }
        }
        $from = $request->get('fromtype');
        $inner_order_id = $request->get('inner_order_id');
        if (!$from) {
            $from = Cookie::get('from');
            $this->innerSendOrderIdFromFromtype($uid_cookie, 1, $from, $inner_order_id);
        } else {
            $this->innerSendOrderIdFromFromtype($uid_cookie, $stats, $from, $inner_order_id);
        }
        //内部派单
        if ($inner_order_id) {
            $this->innerSendOrderIdStats($uid_cookie, $inner_order_id, $stats);
        }

        //from_title_image
        $this->fromTitleImage($request, $uid_cookie);

        if ($test) {
            Cookie::queue(env('COOKIE_AUTH_WEB_WECHAT'), 9, env('U_COOKIE_EXPIRE'), null, null, false, false);
        }
        return $response;
    }

    private function share(Request $request)
    {
        if ($request->has('fromtype') && 'readershare' == $request->get('fromtype')) {
            $bid = $request->get('bid');
            try {
                if ($bid) {
                    $bid_arr = Hashids::decode($bid);
                    isset($bid_arr[0]) && $bid = $bid_arr[0];
                }
            } catch (\Exception $e) {
            }
            $fromflag = $request->get('fromflag', 0);
            $cid = $request->get('fromcid', 0);
            Cookie::queue('reader_share_bid', $bid . '-' . $fromflag, 60);
            Cookie::queue('reader_share_cid', $cid, 60);
        }
    }

    private function isQyMove($channel, $distribution_channel_id)
    {
        $is_yq_move = 0;
        // 新站
        if (isset($channel->is_yq_move) && $channel->is_yq_move) {

            $is_yq_move = 1;
        }
        // 已经迁移过的站，回复也要有老站
        $yqMoveChannel = YqMoveChannel::get_yq_move_channel($distribution_channel_id, 1);
        if (!empty($yqMoveChannel)) {
            //\Log::info('old_has_move_site:'.$distribution_channel_id);
            $is_yq_move = 1;
        }
        return $is_yq_move;
    }

    private function innerSendOrderIdFromFromtype($uid, $stats, $from, $inner_order_id)
    {
        //$inner_send_order_id = ReadRecordService::getInnerSendOrderId($uid);
        $inner_send_order_id = false;
        if (!$inner_send_order_id) {
            if ($from && (starts_with($from, 'custom') || starts_with($from, 'template')) && count(explode('_', $from)) == 2) {
                if (!$inner_order_id) {
                    $this->innerSendOrderIdStats($uid, $from, $stats);
                }
            }
        }
    }

    private function innerSendOrderIdStats($uid, $inner_order_id, $stats)
    {
        try {
            ReadRecordService::setInnerSendOrderId($uid, $inner_order_id);
            if (!$stats) {
                Redis::sadd('push:inner_send_order_id:uv:' . $inner_order_id, $uid);

                Redis::hincrby('push:inner_send_order_id:pv', $inner_order_id, 1);
            }
        } catch (\Exception $e) {
        }
    }

    private function cookieNoCrypt()
    {
        $cookie_key = ['send_order_id', 'from', 'send_order_continue', 'send_order_flag'];
        foreach ($cookie_key as $v) {
            $temp = Cookie::get($v);
            if ($temp && strlen($temp) > 150) {
                try {
                    $temp = decrypt($temp);
                } catch (\Exception $e) {

                }
                if ($v == 'from') {
                    Cookie::queue('from', $temp, env('U_COOKIE_EXPIRE'), null, null, false, false);
                    //Cookie::queue($v, $temp);
                } else {
                    Cookie::queue($v, $temp, env('U_COOKIE_EXPIRE'), null, null, false, false);
                }

            }
        }
    }

    /**
     * 公众号签名@华灯初上
     * @param $params
     * @return string
     */
    protected function getSign($params, $key)
    {
        $url = $this->arr_to_url($params, false);
        $url = $url . '&key=' . $key;

        $sign = md5($url);
        return $sign;
    }

    /**
     * 公众号签名@华灯初上
     * @param $array
     * @param bool $has_sign
     * @return string
     */
    protected function arr_to_url($array, $has_sign = false)
    {
        ksort($array);
        reset($array);
        $arg = "";
        while (list ($name, $val) = each($array)) {
            if ($name == 'sign' && !$has_sign) continue;
            if (strpos($name, "_") === 0)
                continue;
            if (is_array($val))
                $val = join(',', $val);
            if ($val === "")
                continue;
            $arg .= $name . "=" . $val . "&";
        }
        $arg = substr($arg, 0, count($arg) - 2);

        return $arg;
    }

    private function apidAndOpenId($distribution_channel_id, $appid, $openid, $uid, $send_order_id)
    {
        $appid_info = OfficialAccountService::officialAccountByAppid(['appid' => $appid]);
        if (!$appid_info)
            return false;
        if ($appid_info->distribution_channel_id != $distribution_channel_id) {
            return false;
        }
        //ForceSubscribeService::
        $res = ForceSubscribeService::forceSubscribeUsersByUidAndAppid($appid, $uid);
        if ($res) return false;

        $forcesubuser = ForceSubscribeService::forceSubscribeUsersByOpenid(['openid' => $openid]);
        if ($forcesubuser) {
            return false;
        }

        /*$send_order_id = ReadRecordService::getSendOrderId($uid);
        if ($send_order_id) {
            try {
                Redis::hset('force_subscribe_from_send_order_id', $appid . '_' . $uid, $send_order_id);
            } catch (\Exception $e) {
            }

        }*/
        $user_info = ForceSubscribeService::getUserInfoAll($appid, $openid);
        $forcesubuserdata = [
            'appid' => $appid,
            'uid' => $uid,
            'distribution_channel_id' => $distribution_channel_id,
            'last_interactive_time' => date('Y-m-d H:i:s'),
            'openid' => $openid,
            'official_account_id' => 1
        ];
        if ($send_order_id) {
            $forcesubuserdata['send_order_id'] = $send_order_id;
        }
        if ($user_info) {
            isset($user_info['province']) && !empty($user_info['province']) && $forcesubuserdata['province'] = $user_info['province'];
            isset($user_info['nickname']) && !empty($user_info['nickname']) && $forcesubuserdata['nickname'] = $user_info['nickname'];
            isset($user_info['city']) && !empty($user_info['city']) && $forcesubuserdata['city'] = $user_info['city'];
            isset($user_info['country']) && !empty($user_info['country']) && $forcesubuserdata['country'] = $user_info['country'];
            isset($user_info['headimgurl']) && !empty($user_info['headimgurl']) && $forcesubuserdata['headimgurl'] = $user_info['headimgurl'];
            isset($user_info['sex']) && !empty($user_info['sex']) && $forcesubuserdata['sex'] = $user_info['sex'];
        }
        ForceSubscribeService::addForceSubscribeUsers($forcesubuserdata);

        ForceSubscribeService::tempForceSubscribeUsersLastTimeUpdate([
            'openid' => $openid,
            'appid' => $appid,
            'distribution_channel_id' => $distribution_channel_id,
            'last_interactive_time' => date('Y-m-d H:i:s')
        ]);

        return true;
    }

    private function getYqChannleIdByAppid($appid)
    {
        $client = new Client(['timeout' => 3.0]);
        $url = 'http://help.imycmh.com/help/getLinkByAppid?appid=' . $appid;
        Log::info('getYqChannleIdByAppid url is: ' . $url);
        try {
            $result = $client->request('get', $url)->getBody()->getContents();
            $result = json_decode($result, 1);
            Log::info('getYqChannleIdByAppid result is.: ');
            Log::info($result);
            if (isset($result['data']['link']) && !empty($result['data']['link'])) {
                return $result['data']['link'];
            }
        } catch (\Exception $e) {
        }
        return '';
    }

    private function moveUserFromYq($distribution_channel_id, $appid, $openid, $uid)
    {
        /*//is_yq_move
        $channel = ChannelService::getById($distribution_channel_id);
        if(!$channel->is_yq_move){
            return ;
        }
        $move_user = YqMove::where('zsy_uid',$uid)->select('zsy_uid')->first();
        if($move_user){
            return ;
        }*/
        $client = new Client(['timeout' => 3.0]);
        $url = 'http://help.imycmh.com/getUserInfoByOpenid?openid=' . $openid;
        try {
            $result = $client->request('get', $url)->getBody()->getContents();
            if (!$result) {
                return;
            }
            $result = json_decode($result, 1);
            $result_data = isset($result['data']) ? $result['data'] : '';
            if (!$result_data) {
                return;
            }
            if (isset($result_data['uid']) && !empty($result_data['uid'])) {
                //$result_data['read_count'] = 53;
                if ($result_data['read_count'] > 50) {
                    //不补偿
                    $pay_for_balance = 500;
                    $data = [
                        'yq_uid' => $result_data['uid'],
                        'zsy_uid' => $uid,
                        'yq_distribution_channel_id' => $result_data['user']['distribution_channel_id'],
                        'zsy_distribution_channel_id' => $distribution_channel_id,
                        'read_count' => $result_data['read_count'],
                        'yq_balance' => $result_data['user']['balance'],
                        'is_pay' => 0,
                        'pay_for_balance' => $pay_for_balance,
                        'openid' => $openid,
                        'appid' => $appid
                    ];
                    $special = env('YQ_MOVE_SPECIAL');

                    if ($special && in_array($distribution_channel_id, explode(',', $special))) {
                        //特殊梳理
                        $yq_charge_amount = $result_data['order_amoun'];
                        if ($yq_charge_amount > 30) {
                            $pay_for_balance = 3000;
                        } else {
                            $pay_for_balance = $yq_charge_amount * 100;
                        }
                        if ($pay_for_balance < 500) {
                            $pay_for_balance = 500;
                        }
                        if ($pay_for_balance > 3000) {
                            $pay_for_balance = 3000;
                        }
                        $pay_for_balance = (int)$pay_for_balance;

                        $balance = $pay_for_balance + $result_data['user']['balance'];
                        $data['pay_for_balance'] = $pay_for_balance;
                        $data['is_pay'] = 1;
                        YqMove::create($data);
                        UserService::addBalance($uid, $balance, 0, $balance);
                        $flag = false;
                        if (in_array($distribution_channel_id, [160, 4236, 4237, 4241])) {
                            //特殊 回复老站
                            $flag = true;
                        }
                        $this->movePush($distribution_channel_id, $pay_for_balance, $appid, $result_data['user']['distribution_channel_id'], $openid, $flag);
                    } else {
                        $data['is_pay'] = 1;
                        YqMove::create($data);
                        UserService::addBalance($uid, $pay_for_balance, 0, $pay_for_balance);
                        $this->movePush($distribution_channel_id, $pay_for_balance, $appid, $result_data['user']['distribution_channel_id'], $openid, true);
                    }

                } else {
                    //补偿
                    $yq_charge_amount = $result_data['order_amoun'];
                    if ($yq_charge_amount > 30) {
                        $pay_for_balance = 3000;
                    } else {
                        $pay_for_balance = $yq_charge_amount * 100;
                    }
                    if ($pay_for_balance < 500) {
                        $pay_for_balance = 500;
                    }
                    if ($pay_for_balance > 3000) {
                        $pay_for_balance = 3000;
                    }
                    $pay_for_balance = (int)$pay_for_balance;
                    YqMove::create([
                        'yq_uid' => $result_data['uid'],
                        'zsy_uid' => $uid,
                        'yq_distribution_channel_id' => $result_data['user']['distribution_channel_id'],
                        'zsy_distribution_channel_id' => $distribution_channel_id,
                        'read_count' => $result_data['read_count'],
                        'yq_balance' => $result_data['user']['balance'],
                        'is_pay' => 1,
                        'pay_for_balance' => $pay_for_balance,
                        'openid' => $openid,
                        'appid' => $appid
                    ]);
                    $balance = $pay_for_balance + $result_data['user']['balance'];
                    UserService::addBalance($uid, $balance, 0, $balance);
                    $this->movePush($distribution_channel_id, $pay_for_balance, $appid, $result_data['user']['distribution_channel_id'], $openid);
                }
            }
        } catch (\Exception $e) {

        }
    }

    private function movePush($distribution_channel_id, $pay_for_balance, $appid, $old_channel_id, $openid, $need_old = false)
    {
        $move_not_need_push_channel_id = env('MOVE_NOT_NEED_PUSH_CHANNEL_ID');
        if ($move_not_need_push_channel_id && in_array($distribution_channel_id, explode(',', $move_not_need_push_channel_id))) {
            return;
        }
        $data = [];
        if ($pay_for_balance) {
            if ($need_old) {
                $format = "亲爱的用户：\r\n由于原小说站进行网站维护中，为了让您能够继续阅读更多优质小说,我们将在新站中补偿您%s书币，以表达我们诚挚的歉意\r\n\r\n<a href='%s'>点此进入新站</a>\r\n\r\n<a href='%s'>继续老站阅读</a>";
                $url = env('PROTOCOL') . '://site' . encodeDistributionChannelId($distribution_channel_id) . '.' . env('CUSTOM_HOST') . '.com/';
                $content = sprintf($format, $pay_for_balance, $url);
            } else {
                $format = "亲爱的用户：\r\n由于原小说站进行网站维护中，为了让您能够继续阅读更多优质小说,我们将在新站中补偿您%s书币，以表达我们诚挚的歉意\r\n\r\n<a href='%s'>点此进入新站</a>";
                $url = env('PROTOCOL') . '://site' . encodeDistributionChannelId($distribution_channel_id) . '.' . env('CUSTOM_HOST') . '.com/';
                //$old_url = env('PROTOCOL') . '://site' . encodeDistributionChannelId($old_channel_id) . '.chunnuan555.com/continue';
                $old_url = 'http://site' . encodeDistributionChannelId($old_channel_id) . '.imycmh.com/continue';
                $content = sprintf($format, $pay_for_balance, $url, $old_url);
            }

        } else {
            $fromat = "亲爱的用户：\r\n%s新增全新站点，新站拥有海量优质小说，同时原先站点可继续看书\r\n<a href='%s'>点此进入新站</a>\r\n\r\n<a href='%s'>继续老站阅读</a>";
            $new_url = env('PROTOCOL') . '://site' . encodeDistributionChannelId($distribution_channel_id) . '.' . env('CUSTOM_HOST') . '.com/';
            //$old_url = env('PROTOCOL') . '://site' . encodeDistributionChannelId($old_channel_id) . '.chunnuan555.com/continue';
            $old_url = 'http://site' . encodeDistributionChannelId($old_channel_id) . '.imycmh.com/continue';
            $offical = DB::table('official_accounts')->where('appid', $appid)->select('nickname')->first();
            $offical_name = '网站';
            if ($offical && $offical->nickname) {
                $offical_name = $offical->nickname;
            }
            $content = sprintf($fromat, $offical_name, $new_url, $old_url);
        }
        $data['openid'] = $openid;
        $data['appid'] = $appid;
        $data['content'] = $content;
        $data['type'] = 'one_task';
        $data['task_id'] = 1;
        $data['send_time'] = date("Y-m-d H:i:s");
        $send_data = array(
            'send_time' => date("Y-m-d H:i:s"),
            'data' => $data
        );
        Log::info('movePush info');
        Log::info($send_data);
        $delay = 0;
        $job = (new SendTexts($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('send_texts_list');
        dispatch($job);
    }

    private function smartPush(Request $request, $uid)
    {
        $bid = $request->get('bid');
        $fromsource = $request->get('fromsource');
        if (!$fromsource || !$bid) {
            return;
        }
        if ($fromsource != 'smart_push') {
            return;
        }
        $decode_bid_array = Hashids::decode($bid);

        if (!$decode_bid_array)
            return;
        $decode_bid = 0;

        if (isset($decode_bid_array[0]) && !empty($decode_bid_array[0])) {
            $decode_bid = $decode_bid_array[0];
        }
        if (!$decode_bid)
            return;

        //记录pv uv
        try {
            $uv_key = sprintf('%s_%s_uv', $decode_bid, 'smart_push');
            Redis::sadd($uv_key, $uid);
            Redis::HINCRBY('smart_push_test_book', $decode_bid, 1);
            ReadRecordService::setSmartPush($uid, $decode_bid);
        } catch (\Exception $e) {
            Log::info($e);
        }
    }

    protected function notAccessPage()
    {
        return '<html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>网站正在维护中</title></head><body style="padding:0;margin:0;font-size:0"><div style="width:300px;height:100px;margin: 20px auto"><p style="font-size:20px;color:red;text-align:center">网站正在维护中，请联系客服</p><img src="data:image/jpeg;base64, " width=300px ></div></body></html>';
    }

    private function fromTitleImage(Request $request, $uid)
    {
        $from_title_image = $request->get('from_title_image');
        if ($from_title_image) {
            $key = 'smart_push_from_title_image:' . $from_title_image;
            try {
                Redis::hincrby($key, 'click_num', 1);
                Redis::sadd('smart_push_from_title_image_click_uv:' . $from_title_image, $uid);
            } catch (\Exception $e) {
            }

        }
    }

    //短片推唱片
    private function dataAnalysis(Request $request, $uid)
    {
        if (!$request->has('ru')) {
            return;
        }
        $su = $request->get('ru');
        if (!$su) return;

        $su_array = explode('_', $su);

        if (count($su_array) !== 2) {
            return;
        }
        $data = [];
        $arr = ['title' => 1, 'over' => 2];
        if (isset($arr[$su_array[0]])) {
            $data['type'] = $arr[$su_array[0]];
            $data['material_id'] = $su_array[1];
            $data['uid'] = $uid;
            $data['created_at'] = $data['updated_at'] = date('Y-m-d H:i:s');
            try {
                DB::table('data_analysis_visit_stats')->insert($data);
            } catch (\Exception $e) {
            }
        }
    }

    /**
     * 临时统计
     * @param Request $request
     * @param $uid
     */
    private function tempFromWhere(Request $request, $uid)
    {
        $temp_from_where = env('TEMP_FROM_WHERE');
        if (!$temp_from_where) {
            return;
        }
        $from_where = $request->get('fromwhere');
        if (!$from_where) {
            return;
        }
        $url = $request->get('_url', '0');
        if (stripos($url, 'reader') !== false) {
            $temp_from_where_start_end = explode(',', $temp_from_where);
            if (count($temp_from_where_start_end) == 2) {
                if (time() > $temp_from_where_start_end[0] && time() < $temp_from_where_start_end[1]) {
                    try {
                        Redis::sadd('temp_from_where:' . $from_where, $uid);
                    } catch (\Exception $e) {
                    }
                    return;
                }
            }
        }
        return;
    }

    private function recordPrimaryNumberChannleIDUser($distribution_channel_id, $uid)
    {
        if (!is_numeric($distribution_channel_id)) {
            return;
        }
        try {
            Redis::sadd('recordPrimaryNumberChannleIDUser', $uid);
        } catch (\Exception $e) {
        }
    }

    /**
     * 禁止site+数字站点的访问 保留已经充值过的用户和4267站点所有用户
     *  true禁止  false 不禁止
     * @param $distribution_channel_id
     * @return bool
     */
    private function isForbidPrimaryNumberChannleID($distribution_channel_id, $uid)
    {
        $forbid_primary_number_channel_id = env('FORBID_PRIMARY_NUMBER_CHANNEL_ID', '14,2,4267');
        if (is_numeric($distribution_channel_id) &&
            !in_array($distribution_channel_id, explode(',', $forbid_primary_number_channel_id)) &&
            !DB::table('orders')->where('uid', $uid)->where('status', 'PAID')->first()
        ) {
            return true;
        }
        return false;
    }

    /**
     * 特殊渠道的授权登陆
     * @param Request $request
     * @return string
     */
    private function authV2(Request $request, $channel_id)
    {
        if (!$request->has('auth')) return '';
        $auth = $request->get('auth');
        if ($auth != 'v2') {
            return '';
        }

        $h5_scheme = env('PROTOCOL', 'https');
        $domain = _domain();
        $params['redirect_url'] = urlencode($h5_scheme . '://' . $domain . '/oauthCallBackV2');

        $params['timestamp'] = time();
        $info = specialChannelAuthInfo();
        if (!$info || !isset($info[$channel_id])) {
            return '';
        }
        $appid = $info[$channel_id];
        if (!$appid) {
            return '';
        }
        $params['gzh_app_id'] = $appid;

        $params['sign'] = $this->getSign($params, env('OAUTH_KEY'));

        $redirect = env('AUTH_URL') . '?' . http_build_query($params);

        return $redirect;
    }

    /**
     * @param Request $request
     * @param $channel_id
     * @return string
     */
    private function auth(Request $request, $channel_id)
    {

        $appid = env('WECHAT_AUTH_APPID');

        $h5_scheme = env('PROTOCOL', 'https');
        $domain = _domain();
        $params['redirect_url'] = urlencode($h5_scheme . '://' . $domain . '/oauthCallBack');

        $params['timestamp'] = time();
        $info = specialChannelAuthInfoV2();
        if ($info && isset($info[$channel_id]) && !empty($info[$channel_id])) {
            $appid = $info[$channel_id];
        }

        $params['gzh_app_id'] = $appid;

        $params['sign'] = $this->getSign($params, env('OAUTH_KEY'));

        $redirect = env('AUTH_URL') . '?' . http_build_query($params);

        return $redirect;
    }

    //个性化推送
    private function stylePush(Request $request, $uid, $distribution_channel_id)
    {
        $gxhp = $request->get('gxhp');
        if (!$gxhp || !$uid || !$distribution_channel_id) return;

        $date = date('Y-m-d');
        $uv_key = sprintf('push:stylepush:uv:%s:gxhp:%s:date:%s', $distribution_channel_id, $gxhp, $date);
        $pv_key = sprintf('push:stylepush:pv:%s:gxhp:%s:date:%s', $distribution_channel_id, $gxhp, $date);
        try {
            Redis::hset('book_read:' . $uid, 'gxhp', $gxhp);
            Redis::sadd($uv_key, $uid);
            Redis::incr($pv_key);
            Redis::sadd(sprintf('push:stylepush:date:%s', $date), sprintf('%s_%s', $distribution_channel_id, $gxhp));
        } catch (\Exception $e) {
        }
    }

    private function yqTest(Request $request, $uid, $channel_id)
    {
        if (!$request->has('fromtype')) return '';
        $from_type = $request->get('fromtype');
        if (empty($from_type)) {
            return '';
        }
        if ($from_type == 'main') {
            return '';
        }
        if ($request->has('r')) {
            return '';
        }
        //Log::info('1111111111111111111111111111111');
        $param = $request->except('_url');
        if (isset($param['bid'])) unset($param['bid']);
        if (isset($param['cid'])) unset($param['cid']);
        //unset($param['from_type']);
        $other_str = 'r=1';
        if ($param) {
            $other_str = http_build_query($param) . '&' . $other_str;
        }
        //$uri = $request->input('_url');
        $bid = $request->get('bid');
        if (!$bid) return '';
        try {
            $bid_arr = Hashids::decode($bid);
            isset($bid_arr[0]) && $bid = $bid_arr[0];
        } catch (\Exception $e) {
            return '';
        }
        //Log::info('222222222222222222222222222222');
        if (!$bid) return '';
        //Log::info('333333333333333333333333333333');
        //用户是否在样本中
        $yq_book_user = BookUserService::selectUser($uid);
        if (!$yq_book_user) {
            return '';
        }
        $flag = $yq_book_user->flag;
        if (empty($flag)) {
            return '';
        }
        //Log::info('44444444444444444444444444444');
        //如果是group_1 不错操作
        if ($flag == 'group_1') {
            YqUserBidRelationService::create($uid, $bid, 'GROUP_1', 0);
            if ($yq_book_user->type == 'INIT') {
                BookUserService::updateUser($uid, ['type' => 'GROUP_1']);
            }
            return '';
        }
        //Log::info('5555555555555555555555555555');
        if ($flag != 'group_2') {
            return '';
        }
        //Log::info('66666666666666666666666666666');
        //用户的类型是初始类型  区域还没获取
        if ($yq_book_user->type == 'INIT') {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } else {
                $ip = get_client_ip();
            }
            $area = $this->getIpArea($ip);
            $area = $area ? $area : 'unknown';
            $type = $this->isLimit($area);
            $data = ['area' => $area, 'type' => $type];
            if ('ENABLE' == $type) {
                $yq_zsy_test = YqZsyTestService::getByBid($bid);
                if ($yq_zsy_test) {
                    YqUserBidRelationService::create($uid, $bid, 'GROUP_2', $bid);
                    //书在测试列表中
                    $data['bid'] = $bid;
                    BookUserService::updateUser($uid, $data);
                    return '';
                }
                //Log::info('7777777777777777777777777');
                //书不在在测试列表中
                //获取随机获取一本书,获取不到则返回
                $redirect_bids = YqZsyTestService::getRandomBooks($uid, 1);
                $redirect_bid = 0;
                if ($redirect_bids && isset($redirect_bids[0])) {
                    $redirect_bid = $redirect_bids[0];
                }
                if (!$redirect_bid) {
                    BookUserService::updateUser($uid, $data);
                    return '';
                };
                //Log::info('88888888888888888888888888');
                //Log::info($redirect_bids);
                $redirect_book_info = BookConfigService::getBookById($redirect_bid);
                if ($redirect_book_info) {
                    $redirect = $this->getBookReaderUrl($redirect_bid, $channel_id);
                    if ($redirect) {
                        $data['bid'] = $redirect_bid;
                    }
                    YqUserBidRelationService::create($uid, $bid, 'GROUP_2', $redirect_bid);
                    BookUserService::updateUser($uid, $data);
                    return $redirect . '&' . $other_str;
                }
                //Log::info('9999999999999999999999999');
                return '';

            }
            if ('DISABLED' == $type) {
                //禁止访问的区域
                BookUserService::updateUser($uid, $data);
                BookUserService::popUser($uid);
                return '';
            }
            //Log::info('aaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
        }
        if ($yq_book_user->type == 'DISABLED') {
            return '';
        }
        //Log::info('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
        $yq_zsy_test = YqZsyTestService::getByBid($bid);
        //如果书在测试样本中 不跳转
        if ($yq_zsy_test) {
            YqUserBidRelationService::create($uid, $bid, 'GROUP_2', 0);
            return '';
        }
        //Log::info('ccccccccccccccccccccccccccccc');
        // 用户符合条件 且看的书不样本中
        $relate_info = YqUserBidRelationService::getByUidAndBid($uid, $bid);
        if ($relate_info && $relate_info->to_bid) {
            //已经有对应关系
            //如果有阅读记录
            $record_url = $this->readerRecpord($uid, $relate_info->to_bid, $channel_id);
            if ($record_url) return $record_url . '&' . $other_str;
            //没有阅读记录
            $book_url = $this->getBookReaderUrl($relate_info->to_bid, $channel_id);
            //Log::info('dddddddddddddddddddddddddd');
            //Log::info($book_url.'&'.$other_str);
            return $book_url . '&' . $other_str;
        } else {
            //没有对应关系
            //随机获取一本书
            $redirect_bids = YqZsyTestService::getRandomBooks($uid, 1);
            $redirect_bid = 0;
            if ($redirect_bids && isset($redirect_bids[0])) {
                $redirect_bid = $redirect_bids[0];
            }
            if (!$redirect_bid) {
                return '';
            };
            //Log::info('eeeeeeeeeeeeeeeeeeeeeeeeeeeee');
            $redirect = $this->getBookReaderUrl($redirect_bid, $channel_id);
            if ($redirect) {
                $data['bid'] = $redirect_bid;
                //更新对应关系
                BookUserService::updateUser($uid, $data);
                //Log::info('ffffffffffffffffffffffff');
                YqUserBidRelationService::create($uid, $bid, 'GROUP_2', $redirect_bid);
                return $redirect . '&' . $other_str;
            }
            //Log::info('gggggggggggggggggggggggggggggggg');
            return '';
        }
    }

    private function getBookReaderUrl($bid, $channel_id)
    {
        $redirect_book_info = BookConfigService::getBookById($bid);
        if ($redirect_book_info) {
            //Log::info('getBookReaderUrl');
            //Log::info($redirect_book_info);
            $redirect = sprintf(
                'https://site%s.iycdm.com/reader?bid=%s&cid=%s',
                encodeDistributionChannelId($channel_id),
                Hashids::encode($bid),
                $redirect_book_info->first_cid
            );
            return $redirect;
        }
        return '';
    }

    private function readerRecpord($uid, $bid, $channel_id)
    {
        $record_info = null;
        try {
            $record_info = ReadRecordService::getRecordByUidBid($uid, $bid);
        } catch (\Exception $e) {
            return '';
        }

        if (!$record_info) return '';
        $record_info_arr = explode('_', $record_info);

        if (isset($record_info_arr[0])) {
            $cid = $record_info_arr[0];
            if (!$cid) return '';
            $redirect = sprintf(
                'https://site%s.iycdm.com/reader?bid=%s&cid=%s',
                encodeDistributionChannelId($channel_id),
                Hashids::encode($bid),
                $cid
            );
            return $redirect;
        }
        return '';
    }

    private function isLimit($area)
    {
        if ($area == 'unknown') {
            return 'DISABLED';
        }
        $limit_area = ['上海', '北京', '杭州', '南京', '广州'];
        foreach ($limit_area as $a) {
            Log::info('$area: ' . $area . ',$a: ' . $a . PHP_EOL);
            if (mb_strpos($area, $a) !== false) {
                return 'DISABLED';
            }
        }
        return 'ENABLE';
    }

    private function getIpArea($ip)
    {
        $client = new Client(['timeout' => 3.0]);
        $url = 'http://apis.juhe.cn/ip/ip2addr?key=5cb679e201b214cf70106e4bf09ab576&ip=' . $ip;
        $result = null;
        try {
            $result = $client->request('get', $url)->getBody()->getContents();
        } catch (\Exception $e) {
            return '';
        }
        if (!$result) return '';
        $result = json_decode($result, 1);
        $area = '';
        if (isset($result['result']) && !empty($result['result']) && isset($result['result']['area'])) {
            $area = $result['result']['area'];
        }
        return $area;
    }

    private function yun(Request $request, $uid, $distribution_channel_id)
    {
        $uri = $request->input('_url');
        if ($uri && strpos($uri, '/yun/') !== false) {
            return;
        }
        $param = $request->get('yun');
        //Log::info('$param is : '.$param);
        if (!$param) return;
        $bid = $request->get('bid');
        //Log::info('$bid = $request is : '.$bid);
        $send_order_info = SendOrderService::getRedirectUrlById($param);
        //Log::info('$send_order_info  is : ');
        //Log::info($send_order_info);
        if ($bid) {
            $bid_arr = Hashids::decode($bid);
            isset($bid_arr[0]) && $bid = $bid_arr[0];
        }
        //Log::info('bid is'.$bid);
        if (!$send_order_info) return;
        if ($send_order_info->book_id && $send_order_info->book_id != $bid) return;
        if ($send_order_info->distribution_channel_id != $distribution_channel_id) return;
        if($uid){
            try{
                Redis::hset('book_read:' . $uid, 'send_order_id', $param);
            }catch (\Exception $e){}
        }
        is_numeric($bid) && $this->specialChannelIdStats($param, $distribution_channel_id, $uid, $bid);
        $key = date('Y-m-d');
        Cookie::queue('send_order_id', $param, env('U_COOKIE_EXPIRE'), null, null, false, false);
        $send_order_flag = Cookie::get('send_order_flag');
        $send_orders = explode(',', $send_order_flag);
        //uv
        if (!Cookie::get('send_order_flag_' . $param) && !in_array($param, $send_orders)) {
            Redis::hincrby('send_order_uv_' . $param, $key, 1);
            Redis::hincrby('send_order_uv_' . $param, 'total', 1);
            //Cookie::queue('send_order_flag_'.$param,$param, env('U_COOKIE_EXPIRE'), null, null, false, false);
            array_push($send_orders, $param);
            $str = implode(',', $send_orders);
            Cookie::queue('send_order_flag', $str, env('U_COOKIE_EXPIRE'), null, null, false, false);
        }

        if (Cookie::get('send_order_flag_' . $param)) {
            array_push($send_orders, $param);
            $str = implode(',', $send_orders);
            Cookie::queue('send_order_flag', $str, env('U_COOKIE_EXPIRE'), null, null, false, false);
            Cookie::queue('send_order_flag_' . $param, null, -1);
        }
        //pv
        Redis::hincrby('send_order_pv_' . $param, $key, 1);//每天
        Redis::hincrby('send_order_pv_' . $param, 'total', 1);//汇总
        Redis::sadd('send_order' . $key, $param);

        $uv = Redis::hget('send_order_uv_' . $param, $key);

        $uv && $uv >= 20 && SendOrderService::updateSendOrderTime($param);
    }

    /**
     * 用户从A连接推送的书，进入后，被标记bookid+派单id，之后所有的统计计算到该派单下
     * @param int $send_order_id
     * @param int $distribution_channel_id
     * @param int $uid
     * @param int $bid
     */
    private function specialChannelIdStats(
        int $send_order_id,
        int $distribution_channel_id,
        int $uid,
        int $bid
    ):void
    {

        if (!$bid || !$distribution_channel_id || !$uid || !$send_order_id)
            return;
        $specialChannelIdStats = env('SPECIAL_CHANNEL_STATS', 211);
        if (!in_array($distribution_channel_id, explode(',', $specialChannelIdStats))) {
            return;
        }
        WapVisitStatService::specialChannelIdStatsMarkUser($uid, $bid, $send_order_id);
        return;
    }

    private function authCallBack(Request $request)
    {
        $auth_uid = $request->get('auth_uid');
        $atime = $request->get('atime');
        $sign = $request->get('sign');
        if (!$auth_uid || !$atime || !$sign) return 0;
        if (!is_numeric($auth_uid) || !is_numeric($atime)) return 0;
        if ((time() - $atime) > 5) return 0;
        if (get_sign(compact('auth_uid', 'atime')) !== $sign) return 0;
        Cookie::queue(env('COOKIE_AUTH_WEB_WECHAT'), $auth_uid, env('U_COOKIE_EXPIRE'), null, null, false, false);
        return $auth_uid;
    }

    private function getAppSecretByAppId($appId)
    {
        $info = DB::table('official_setting')->where('appid', $appId)->select('secret')->first();
        if ($info) {
            return $info->secret;
        }
        return '';
    }

    private function authReduceRedirect(Request $request,$distribution_channel_id,$send_order_id){
        $h5_scheme = env('H5_SCHEME', 'https');
        $params = $request->except('_url');
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = get_client_ip();
        }
        $params['ip'] = $ip;
        if(isset($params['auth_uid'])) unset($params['auth_uid']);
        if(isset($params['atime'])) unset($params['atime']);
        if(isset($params['sign'])) unset($params['sign']);
        $url = str_replace('http://', $h5_scheme . '://', url()->current() . '?' . http_build_query($params));
        unset($params['ip']);
        $params['redirect_url'] = urlencode($url);
        $params['timestamp'] = time();
        $params['channel_id'] = $distribution_channel_id;
        $params['sid'] = $send_order_id;
        $params['sign'] = $this->getSign($params, env('OAUTH_KEY'));

        //新的授权
        $auth_redirect_one_appids = specialChannelAuthInfoV2();
        $auth_redirect_two_appids = specialChannelAuthInfo();
        if($auth_redirect_one_appids && isset($auth_redirect_one_appids[$distribution_channel_id])){
            //授权一次
            $callback = env('AUTH_CALLBACK_URL_V2');
            $appid = $auth_redirect_one_appids[$distribution_channel_id];
        }elseif($auth_redirect_two_appids && isset($auth_redirect_two_appids[$distribution_channel_id]) ){
            //授权二次
            $callback = env('AUTH_CALLBACK_URL_V2_2');
            $appid = env('WECHAT_AUTH_APPID');
        }else{
            //默认授权
            $callback = env('AUTH_CALLBACK_URL_V2');
            $appid = env('WECHAT_AUTH_APPID');
        }
        $params['appid'] = $appid;
        $secret = $this->getAppSecretByAppId($appid);

        $options = [
            'app_id' => $appid,
            'secret' => $secret,
            'oauth' => [
                'scopes' => ['snsapi_base'],
                'callback' => $callback . '?' . http_build_query($params),
            ],
        ];
        return $options;
    }
}
