<?php

namespace App\Jobs;

use App\Jobs\Job;
use App\Modules\OfficialAccount\Models\ForceSubscribeDelayMsg;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request as GuzzleRequest;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\WechatController;

class ForceSubscribeDelayMsgJob extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    private $data;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($data)
    {
        $this->data = $data;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        Log::info('~~~~~~~~~~~~~~~~~~开始执行关注后延时回复消息队列~~~~~~~~~~~~~~~~~~');
        Log::info('参数: '.json_encode($this->data, 256));

        $client = new Client();
        $access_token_list = [];
        $this->data = (object)$this->data;

        //用户类型是否满足条件
        $is_access = self::msgUserTypeIsAccess($this->data->distribution_channel_id,$this->data->time_delay,$this->data->openid,$msg);
        if(!$is_access) {
            DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->where('id',$this->data->id)
                ->update([
                    'send_status'=>$msg,
                    'send_time'=>date('Y-m-d H:i:s'),
                    'updated_at'=>date('Y-m-d H:i:s'),
                    'send_result'=>''
                ]);
        }
        if(isset($access_token_list[$this->data->appid])){
            $access_token = $access_token_list[$this->data->appid];
        }else{
            $access_token = self::getAccessToken($this->data->appid);
            if($access_token){
                $access_token_list[$this->data->appid] = $access_token;
            }
        }
        if ($this->data->mode == 1 && $this->data->link) {
            if(stripos($this->data->link,'?') !== false){
                $link = $this->data->link.'&fromtype=subscribe_delay_'.$this->data->id;
            }else{
                $link = $this->data->link.'?fromtype=subscribe_delay_'.$this->data->id;
            }
        }

        if($access_token){
            if ($this->data->mode == 1) {
                $result = self::send($client,$access_token,$this->data->openid,textDecode($this->data->title),textDecode($this->data->desc),$link,$this->data->icon);
            }elseif ($this->data->mode == 2) {
                $nickname = DB::connection('api_mysql')->table('users')->where(['openid'=>$this->data->openid, 'distribution_channel_id'=>$this->data->distribution_channel_id])->value('nickname');
                $content = textDecode(str_replace('{user}', $nickname, $this->data->content));
                $result = self::sendMsg($client,$access_token,$this->data->openid,$content);
                $content = $nickname = null;
            }

            $result_array = \GuzzleHttp\json_decode($result,1);
            if(isset($result_array['errcode']) && $result_array['errcode'] == 0){
                $send_status = 'send_success';
            }else{
                $send_status = 'send_fail';
            }

            DB::connection('api_mysql')->table('force_subscribe_delay_msg_send_record')->where('id',$this->data->id)
                ->update([
                    'send_status'=>$send_status,
                    'send_time'=>date('Y-m-d H:i:s'),
                    'updated_at'=>date('Y-m-d H:i:s'),
                    'send_result'=>$result
                ]);
        }
        Log::info('~~~~~~~~~~~~~~~~~~结束执行关注后延时回复消息队列~~~~~~~~~~~~~~~~~~');
    }

    public static function msgUserTypeIsAccess($distribution_channel_id,$time_delay,$openid,&$msg){
        $forceSubscribeDelayMsg = ForceSubscribeDelayMsg::where('distribution_channel_id',$distribution_channel_id)
            ->where('time_delay',$time_delay)
            ->where('is_show',1)
            ->where('is_enable',1)
            ->select('user_type')
            ->first();
        $msg = '';
        if(!$forceSubscribeDelayMsg) {
            $msg = 'sys-error';
            return false;
        }
        if(strtoupper($forceSubscribeDelayMsg->user_type) == 'ALL') return true;
        //已付费用户
        $force_subscribe_user = DB::connection('api_mysql')->table('temp_force_subscribe_users')->where('openid',$openid)->where('is_subscribed',1)->select('uid')->first();
//        if(!$force_subscribe_user) {
//            $msg = 'no subscribe';
//            return false;
//        }
//        if(!$force_subscribe_user->uid) {
//            $msg = 'no subscribe uid';
//            return false;
//        }
        if(strtoupper($forceSubscribeDelayMsg->user_type) == 'PAID'){
            if (isset($force_subscribe_user->uid) && !empty($force_subscribe_user->uid)) {
                $paid_count = DB::connection('api_mysql')->table('orders')->where('uid',$force_subscribe_user->uid)->where('status','PAID')->count();
                if($paid_count && $paid_count >0)
                    return true;
                $msg = 'need paid';
                return false;
            } else {
                return false;
            }
        }
        //未已付费用户
        if(strtoupper($forceSubscribeDelayMsg->user_type) == 'UNPAID'){
            if (isset($force_subscribe_user->uid) && !empty($force_subscribe_user->uid)) {
                $paid_count = DB::connection('api_mysql')->table('orders')->where('uid',$force_subscribe_user->uid)->where('status','PAID')->count();
                if($paid_count && $paid_count >0) {
                    $msg = 'need unpaid';
                    return false;
                }
                return true;
            }elseif ($force_subscribe_user) {
                return true;
            }else {
                return false;
            }
        }
        $msg = 'unknown type';
        return false;
    }

    private static function getAccessToken($appid){
        try{
            $WechatController = new WechatController($appid);
            $accessToken = $WechatController->app->access_token;
            $token = $accessToken->getToken();
            return $token;
        }catch(\Exception $e){
            \Log::error($e);
        }
        return '';
    }

    // 发送图文消息
    private static function send(Client $client,$access_token,$openid,$title,$description,$url,$picurl){
        $push_url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token;
        $request = new GuzzleRequest('post',$push_url,[],\GuzzleHttp\json_encode([
            'touser'=>$openid,
            'msgtype'=>'news',
            'news'=>[
                'articles'=>[compact('title','description','url','picurl')]
            ]
        ],JSON_UNESCAPED_UNICODE));
        try{
            return $client->send($request)->getBody()->getContents();
        }catch (\Exception $e){}
        return '';
    }

    // 发送文字消息
    private static function sendMsg(Client $client,$access_token,$openid,$content){
        $push_url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token;
        $request = new GuzzleRequest('post',$push_url,[],\GuzzleHttp\json_encode([
            'touser'=>$openid,
            'msgtype'=>'text',
            'text'=>[
                'content'=>$content
            ]
        ],JSON_UNESCAPED_UNICODE));
        try{
            return $client->send($request)->getBody()->getContents();
        }catch (\Exception $e){}
        return '';
    }

    public function failed(\Exception $exception)
    {
        Log::error('关注后延迟消息发送异常,异常原因: '.$exception->getMessage());
    }
}
