<?php
/**
 * Created by sublime.
 * User: wosinC
 * Date: 2017/12/2
 * Time: 上午11:39
 */

namespace App\Modules\OfficialAccount\Services;
use App\Modules\OfficialAccount\Models\WechatTemplateMsgs;
use App\Modules\OfficialAccount\Services\ForceSubscribeService;
use App\Modules\OfficialAccount\Models\ForceSubscribeUsers;
use App\Modules\OfficialAccount\Models\OfficialAccount;
use App\Modules\OfficialAccount\Models\OfficialCustomMsg;
use App\Modules\OfficialAccount\Models\CustomMsgSwitchs;
use App\Modules\OfficialAccount\Models\CustomMsgSwitchsMsgs;
use App\Modules\OfficialAccount\Models\CustomSendMsgs;
use App\Modules\OfficialAccount\Models\DistributionChannelSetting;
use App\Modules\OfficialAccount\Models\OfficialImgtextUrls;
use App\Modules\User\Services\ReadRecordService;
use App\Modules\User\Services\UserService;
use App\Modules\Book\Services\BookConfigService;
use App\Modules\OfficialAccount\Services\OfficialAccountService;
use App\Modules\Promotion\Services\PromotionService;
use App\Modules\Channel\Services\ChannelService;
use App\Modules\OfficialAccount\Models\MediaCustomer;
use App\Modules\OfficialAccount\Models\CustomPushActivitys;
use App\Modules\OfficialAccount\Models\CustomSendDayStats;
use GuzzleHttp\Client;
use App\Libs\OSS;
use Redis;
use App\Jobs\SendNews;
use App\Jobs\SendTemplate;
use App\Jobs\SendTexts;
use App\Jobs\CustomMsgSendJob;

class TemplateCustomSendService
{

    /**
     * @return int|void toCheckAndSendCustomMsg
     * 查找并发送模板消息
     */
    static function toCheckAndSendTemplateMsg()
    {

        try {
        	\Log::info('toCheckAndSendTemplateMsg_start');

            //查找模板消息并发送
            $statusPram = '1';
            $allStandByWechatTemplateMsgs = WechatTemplateMsgs::wechatTemplateMsgsByStatusStandBy($statusPram);
            $allStandByWechatTemplateMsgsArray = [];
            if ($allStandByWechatTemplateMsgs){

                //先单独更新数据库 把要发送的状态改为8 以免发送期间超时，导致重复发送
                for ($x=0; $x < count($allStandByWechatTemplateMsgs); $x++) {

                    $wechatTemplateMsgs = $allStandByWechatTemplateMsgs[$x];

                    $send_time = $wechatTemplateMsgs['send_time'];
                    if (strtotime($send_time) - time() > 600) { //发送时间大于当前时间10分钟
                        continue;
                    } else {
                        \Log::info('========现将模板消息设置成发送状态 "8" 用户不能操作（删除，编辑，停止） = ' . $wechatTemplateMsgs['id']);
                        $wechatTemplateMsgs['status'] = '8';
                        $wechatTemplateMsgs->save();
                        $officialAccountArray = $wechatTemplateMsgs->toArray();
                        Redis::hset('send_wechat_msg:task_id:' . $wechatTemplateMsgs['id'], 'wechat_msg', json_encode($officialAccountArray));
                        $allStandByWechatTemplateMsgsArray[] = $wechatTemplateMsgs;
                    }
                }

                for ($x=0; $x < count($allStandByWechatTemplateMsgsArray); $x++){

                    $wechatTemplateMsgs = $allStandByWechatTemplateMsgsArray[$x];
                    \Log::info($wechatTemplateMsgs);

//                    $send_time = $wechatTemplateMsgs['send_time'];
//                    if (strtotime($send_time) - time() > 600){ //发送时间大于当前时间10分钟
//                        continue;
//                    }

                    $wechatTemplateMsgs['redirect_url'] = self::redirect_url_add_param($wechatTemplateMsgs['redirect_url'],$wechatTemplateMsgs['id'],'template',false);
                    \Log::info('template_redirect_url_convert：id:'.$wechatTemplateMsgs['id'].' redirect_url:'.$wechatTemplateMsgs['redirect_url']);

                    $appid = $wechatTemplateMsgs['appid'];
                    $template_id = $wechatTemplateMsgs['template_id'];
                    $template_content = $wechatTemplateMsgs['template_content'];
                    $origin_template_content = $template_content; 
                    $redirect_url = $wechatTemplateMsgs['redirect_url'];
                    // 新版要自动添加域名
                    $redirect_url = self::checkAddDomain($wechatTemplateMsgs['distribution_channel_id'],$redirect_url);
                    \Log::info('checkAddDomain_after:distribution_channel_id:'.$wechatTemplateMsgs['distribution_channel_id'].' redirect_url:'.$redirect_url);
                    $task_id = $wechatTemplateMsgs['id'];
                    $send_time = $wechatTemplateMsgs['send_time'];
                    $is_full_send = isset($wechatTemplateMsgs['is_full_send'])?$wechatTemplateMsgs['is_full_send']:0;

                    \Log::info('-----------------模板消息参数--------------appid = '.$appid.', channelid = '.$wechatTemplateMsgs['distribution_channel_id']);
                    \Log::info('========发送的模板消息内容========== template_content');
                    \Log::info($template_content);
                    //1,通过筛选得到条件符合的强关用户
                    $skip = 0;
                    $next_openid = '';
                    $loop = 0;
                    while ( $skip <= 2500000) {
                    	$loop++;
                        \Log::info('-------------模板消息-----分页取强关用户，目前页数----------'.$skip.' is_full_send:'.$is_full_send.' task_id:'.$task_id.' loop:'.$loop);
                        $users = array();
                        // 全服务号粉丝发，要记录next_openid
                        if($is_full_send){
                        	if($loop > 1 && empty($next_openid)){
                        		\Log::info('send_template_appid:'.$appid.' break,skip:'.$skip);
                        		break;
                        	}
                        	$user_res = ForceSubscribeService::getFullOfficialAccountUsers($appid,$next_openid);
                        	$users = $user_res['openids'];// TODO格式化成一样的格式
                        	$next_openid = $user_res['next_openid'];
                        }else{
                        	$users = ForceSubscribeService::forceUserCountByTemplatePrams($appid,$wechatTemplateMsgs['distribution_channel_id'],$wechatTemplateMsgs['subscribe_time'],$wechatTemplateMsgs['sex'],$wechatTemplateMsgs['balance'],$wechatTemplateMsgs['category_id'],$wechatTemplateMsgs['order_type'],$skip);
                        }
                        \Log::info('-----------------实际发送模板消息用户数量-------------'.count($users).' $next_openid：'.$next_openid);
//                         \Log::info($users);
                        $skip += count($users);
//                         continue;
//                         die('end2');
                        if(count($users)>0){
                            for ($i=0; $i < count($users); $i++) {
                            	
                            	// 占位符替换
                            	$place_holder_params = array();
                            	$place_holder_params['nickname'] = isset($users[$i]['nickname'])?$users[$i]['nickname']:'';
                            	\Log::info('openid:'.$users[$i]['openid'].' nickname:'.$place_holder_params['nickname']);
                            	$template_content = ForceSubscribeService::change_placeholder($origin_template_content,$place_holder_params);
                            	
                                //2，循环用户发送模板消息
                                //发送到最后一条时，将
                                if ($i == count($users)-1) {

                                    $data = array();
                                    $data['statusstr'] = (time());
                                    $data['openid'] = $users[$i]['openid'];
                                    $data['appid'] = $appid;
                                    $data['template_id'] = $template_id;

                                    //4，通过RebitMQ发送模板消息
                                    // $data['template_content'] = $templateSendContents;
                                    $data['template_content'] =str_replace(".DATA","",$template_content);
                                    $data['type'] = 'last_task';// last_task,one_task
                                    $data['url'] = $redirect_url;
                                    $data['task_id'] = $task_id;
                                    $data['send_time'] = $send_time;
                                    $send_data=array(
                                        'send_time'=>$send_time,
                                        'data' => $data
                                    );

                                    $now_time = strtotime($send_time)-time();
                                    $delay = $now_time < 0 ? 0:$now_time;
                                    
                                    \Log::info('------------------发送最后一条模板消息----------task_id = '.$task_id.', 时间差 = '.$now_time.' openid:'.$data['openid']);
                                    $job = (new SendTemplate($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('send_template_list');
                                    dispatch($job);


                                }else{
                                    $data = array();
                                    $data['statusstr'] = (time());
                                    $data['openid'] = $users[$i]['openid'];
                                    $data['appid'] = $appid;
                                    $data['template_id'] = $template_id;

                                    \Log::info('========================[[[[send template message]]]]====================');
                                    \Log::info(str_replace(".DATA","",$template_content));
                                    $data['template_content'] =str_replace(".DATA","",$template_content);
                                    $data['type'] = 'one_task';// last_task,one_task
                                    $data['url'] = $redirect_url;
                                    $data['task_id'] = $task_id;
                                    $data['send_time'] = $send_time;
                                    $send_data=array(
                                        'send_time'=>$send_time,
                                        'data' => $data
                                    );
                                    $now_time = strtotime($send_time)-time();
                                    $delay = $now_time < 0 ? 0:$now_time;

                                    \Log::info('========================发送模板消息 不是最后一条模板=================task_id = '.$task_id.'. openid = '.$data['openid'].', 时间差 = '.$delay);
                                    $job = (new SendTemplate($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('send_template_list');
                                    dispatch($job);

                                }

                            }

                        }else{
                            \Log::info('========================发送模板消息_没找到用户===================='.$task_id);
                            break;
                        }

                       
                    }

                    //更新模板消息的用户数量并更新redis
                    \Log::info('========================更新模板消息并存redis====================task_id = '.$task_id);
                    $wechatTemplateMsgs['user_num'] = $skip;
                    // 若没有用户，则直接更新为已发送
                    if($skip == 0){
                    	\Log::info('has_no_template_users:'.$wechatTemplateMsgs['id']);
                    	$wechatTemplateMsgs['status'] = '3';
                    }
                    $wechatTemplateMsgs->save();

                    $officialAccountArray = $wechatTemplateMsgs->toArray();
                    Redis::hset('send_wechat_msg:task_id:'.$wechatTemplateMsgs['id'], 'wechat_msg', json_encode($officialAccountArray));


                }
            }else{
                \Log::info('========================！！！数据库中没有要发送的模板消息！！！====================');
            }


        } catch (\Exception $e) {
            \Log::info('========================循环用户发送模板消息时报错====================');
            \Log::info($e->getMessage());
        }

    }


    /**
     * @return int|void toCheckAndSendCustomMsg
     * 查找并发送客服消息
     */
    static function toCheckAndSendCustomMsg()
    {
        //
        try {

            //查找模板消息并发送
            $statusPram = '1';
            $allStandByWechatCustomMsgs = CustomSendMsgs::customSendMsgsByStatusStandBy($statusPram);
//             \Log::info($allStandByWechatCustomMsgs);
            $allStandByWechatCustomMsgsArray = [];
            if ($allStandByWechatCustomMsgs) {

                //先单独更新数据库 把要发送的状态改为8 以免发送期间超时，导致重复发送
                for ($x = 0; $x < count($allStandByWechatCustomMsgs); $x++) {

                    $customSendMsgsPrams = $allStandByWechatCustomMsgs[$x];

                    $send_time = $customSendMsgsPrams['send_time'];

                    if (strtotime($send_time) - time() > 600) { //发送时间大于当前时间10分钟
                        continue;
                    } else {
                        \Log::info('========现将客服消息设置成发送状态 "8" 用户不能操作（删除，编辑，停止） = ' . $customSendMsgsPrams['id']);
                        $customSendMsgsPrams['status'] = '8';
                        $customSendMsgsPrams->save();

                        $officialAccountArray = $customSendMsgsPrams->toArray();
                        Redis::hset('send_wechat_msg:task_id:' . $customSendMsgsPrams['task_id'], 'wechat_msg', json_encode($officialAccountArray));
                        $allStandByWechatCustomMsgsArray[] = $customSendMsgsPrams;
                    }
                }

                for ($x = 0; $x < count($allStandByWechatCustomMsgsArray); $x++) {

                    $customSendMsgsPrams = $allStandByWechatCustomMsgsArray[$x];
                    // 转化链接url
                    $customSendMsgsPrams['content'] = self::convert_custom_content($customSendMsgsPrams['content'],$customSendMsgsPrams['id'],$customSendMsgsPrams['distribution_channel_id'],$customSendMsgsPrams['trusteeship']);

                    $appids = $customSendMsgsPrams['appid'];
                    $is_full_send = isset($customSendMsgsPrams['is_full_send'])?$customSendMsgsPrams['is_full_send']:0;
                    \Log::info('------------------客服消息强关用户,appids：'.$appids.' is_full_send:'.$is_full_send);

                    $appidArray  = explode(',', $appids);

                    $usercountnum = 0;

                    for ($j=0; $j < count($appidArray); $j++) {

                        $skip = 0;
                        $next_openid = '';
                        $loop = 0;

                        while ( $skip <= 2500000) {
                        	$loop++;

                            \Log::info('------------------分页取强关用户，目前页数----------'.$skip.' loop:'.$loop.' next_openid:'.$next_openid);
                            $users = array();

                            // 全服务号粉丝发，要记录next_openid
                            if($is_full_send){
                            	// 防止异常
                            	if($loop > 1 && empty($next_openid)){
                            		\Log::info('send_template_appid:'.$appidArray[$j].' break,skip:'.$skip);
                            		break;
                            	}
                            	try{
                            		$user_res = ForceSubscribeService::getFullOfficialAccountUsers($appidArray[$j],$next_openid);
                            		$users = $user_res['openids'];// TODO格式化成一样的格式
                            		$next_openid = $user_res['next_openid'];
                            	} catch (\Exception $e) {
						    		\Log::info($e);
						    	}

                            }else{
                            	//5,获取所选条件下筛选出的用户
                            	$sign_time = 'z';
                            	$users = ForceSubscribeService::forceUserCountByCustomPrams($appidArray[$j],$customSendMsgsPrams['distribution_channel_id'],$customSendMsgsPrams['subscribe_time'],$customSendMsgsPrams['sex'],$customSendMsgsPrams['balance'],$customSendMsgsPrams['category_id'],$customSendMsgsPrams['order_type'],$sign_time,$skip);
                            }
                            \Log::info('--------------------users_num:'.count($users));
//                             continue;

                            if (count($users)>0) {

                                $usercountnum += count($users);

                                for ($i=0; $i < count($users); $i++) {

                                    if ($i == count($users)-1) {

                                        // \Log::info('--------------------客服消息接收用户 last_task');
                                        // \Log::info($users[$i]['openid']);
                                        // \Log::info($appidArray[$j]);
                                        //  7，循环用户发送客服消息
                                        $data = array();
                                        $data['openid'] = $users[$i]['openid'];
                                        $data['appid'] = $appidArray[$j];
                                        $data['news_content'] = $customSendMsgsPrams['content'];
                                        $data['type'] = 'last_task';
                                        $data['task_id'] = $customSendMsgsPrams['task_id'];
                                        $data['send_time'] = $customSendMsgsPrams['send_time'];
                                        $send_data=array(
                                            'send_time'=>$customSendMsgsPrams['send_time'],
                                            'data' => $data
                                        );

                                        $now_time = strtotime($customSendMsgsPrams['send_time'])-time();

                                        $delay = $now_time < 0 ? 0:$now_time;
                                        //\Log::info('start_dispatch:'.$data['openid'].' send_time:'.$customSendMsgsPrams['send_time'].' diff:'.$now_time.' dealy:'.$delay.' task_id:'.$customSendMsgsPrams['task_id']);
                                        
                                        // \Log::info('客服消息找到用户并发送===================================');
                                        // \Log::info($data['openid']);
                                        // \Log::info($data['appid']);
                                        // \Log::info($data['news_content']);
                                        //\Log::info('------------------发送最后一条客服消息----------'.$customSendMsgsPrams['task_id'].' openid:'.$data['openid']);
                                        $job = (new SendNews($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('send_news_list');
                                        dispatch($job);

                                    }else{

                                        // \Log::info('--------------------客服消息接收用户 one_task');
                                        // \Log::info($users[$i]['openid']);
                                        // \Log::info($appidArray[$j]);
                                        //7，循环用户发送客服消息
                                        $data = array();
                                        $data['openid'] = $users[$i]['openid'];
                                        $data['appid'] = $appidArray[$j];
                                        $data['news_content'] = $customSendMsgsPrams['content'];
                                        $data['type'] = 'one_task';
                                        $data['task_id'] = $customSendMsgsPrams['task_id'];
                                        $data['send_time'] = $customSendMsgsPrams['send_time'];
                                        $send_data=array(
                                            'send_time'=>$customSendMsgsPrams['send_time'],
                                            'data' => $data
                                        );

                                        $now_time = strtotime($customSendMsgsPrams['send_time'])-time();
                                        $delay = $now_time;
                                        $delay = $now_time < 0 ? 0:$now_time;
                                        //\Log::info('start_dispatch:'.$data['openid'].' send_time:'.$customSendMsgsPrams['send_time'].' diff:'.$now_time.' dealy:'.$delay.' task_id:'.$customSendMsgsPrams['task_id']);
         
                                        //\Log::info('------------------发送客服消息----------'.$customSendMsgsPrams['task_id'].' openid:'.$data['openid']);
                                        $job = (new SendNews($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('send_news_list');
                                        dispatch($job);

                                    }

                                }
                            }else{
                                \Log::info('------------------发送客服消息没有查找到强关用户----------'.$customSendMsgsPrams['task_id']);
                                break;
                            }

                            $skip += count($users);

                        }

                    }

                    $customSendMsgsPrams['user_num'] = $usercountnum;
                    // 若没有用户，则直接更新为已发送
                    if($usercountnum == 0){
                    	\Log::info('has_no_custom_users:'.$customSendMsgsPrams['task_id']);
                    	$customSendMsgsPrams['status'] = '3';
                    }
                    \Log::info('------------------更新发送用户----------'.$customSendMsgsPrams['task_id'].' usercountnum:'.$usercountnum);
                    $customSendMsgsPrams->save();

                }
            }else{

                \Log::info('========================！！！数据库中没有要发送的客服消息！！！====================');

            }

        } catch (\Exception $e) {
            \Log::info('===================================发送客服消息报错');
            \Log::info($e->getMessage());
        }
    }
    
    /**
     * 转换客服消息内容
     * 1条--新版
     * @param unknown_type $content
     * @return string
     */
    public static function convert_custom_content($content,$mark_str,$distribution_channel_id,$trusteeship=0){
    	\Log::info('convert_custom_content_start:');
    	$_contents = json_decode($content);
//     	\Log::info('convert_custom_content_before:');
//     	\Log::info($_contents);
    	$new_contents = null;
    	// 智能托管,加上各自渠道域名，统计精确到图文每条
    	if($trusteeship){
    		$origin_mark_str = $mark_str;
    		foreach($_contents as $key=>$_content){
    			$url = env('PROTOCOL').'://site'.encodeDistributionChannelId($distribution_channel_id).'.'.env('CUSTOM_HOST').'.com'.$_content[2]->url;
    			$mark_str = $origin_mark_str.'_'.($key+1).'&source=wechatmsg';// source能让用户继续阅读
    			\Log::info('convert_custom_content_url:'.$url.' mark_str:'.$mark_str);
    			$_contents[$key][2]->url = self::redirect_url_add_param($url,$mark_str,'custom',true);
    			$new_contents[] = $_contents[$key];
    			break;
    		}
    	}
    	// 非托管
    	else{
    		$origin_mark_str = $mark_str;
    		$send_type = 'custom';
    		// 智能推送不加前缀
    		if(strpos($origin_mark_str,'smart_push_') > -1){
    			$send_type = 'smart_push';
    			$origin_mark_str = str_replace('smart_push_','',$origin_mark_str);
    		}
    		\Log::info('origin_mark_str:'.$origin_mark_str);

    		foreach($_contents as $key=>$_content){

    			// 新版要自动添加域名
    			$_content[2]->url = self::checkAddDomain($distribution_channel_id,$_content[2]->url);
    			
    			$mark_str = $origin_mark_str.'&source=wechatmsg';// source能让用户继续阅读
    			$_contents[$key][2]->url = self::redirect_url_add_param($_content[2]->url,$mark_str,$send_type,false);
    			$new_contents[] = $_contents[$key];
    			break;
    		}
    	}
//     	\Log::info('convert_custom_content_after:');
//     	\Log::info($new_contents);
    	$_convert_contents = json_encode($new_contents);
    	
    	return $_convert_contents;
    }
    
    /**
     * 转换客服消息内容
     * 多条--老版
     * @param unknown_type $content
     * @return string
     */
    public static function convert_custom_content_multy($content,$mark_str,$distribution_channel_id,$trusteeship=0){
    	\Log::info('convert_custom_content_start:');
    	$_contents = json_decode($content);
    	// 智能托管,加上各自渠道域名，统计精确到图文每条
    	if($trusteeship){
    		$origin_mark_str = $mark_str;
    		foreach($_contents as $key=>$_content){
    			$url = env('PROTOCOL').'://site'.encodeDistributionChannelId($distribution_channel_id).'.'.env('CUSTOM_HOST').'.com'.$_content[2]->url;
    			$mark_str = $origin_mark_str.'_'.($key+1).'&source=wechatmsg';// source能让用户继续阅读
    			\Log::info('convert_custom_content_url:'.$url.' mark_str:'.$mark_str);
    			$_contents[$key][2]->url = self::redirect_url_add_param($url,$mark_str,'custom',true);
    		}
    	}
    	// 非托管
    	else{
    		$origin_mark_str = $mark_str;
    		$send_type = 'custom';
    		// 智能推送不加前缀
    		if(strpos($origin_mark_str,'smart_push_') > -1){
    			$send_type = 'smart_push';
    			$origin_mark_str = str_replace('smart_push_','',$origin_mark_str);
    		}
    		\Log::info('origin_mark_str:'.$origin_mark_str);
    		foreach($_contents as $key=>$_content){
    			$mark_str = $origin_mark_str.'&source=wechatmsg';// source能让用户继续阅读
    			$_contents[$key][2]->url = self::redirect_url_add_param($_content[2]->url,$mark_str,$send_type,false);
    		}
    	}
    	
    	$_convert_contents = json_encode($_contents);
    	//\Log::info('convert_custom_content_after:');
    	//\Log::info($_convert_contents);
    	return $_convert_contents;
    }
    
    /**
     * 跳转地址加参
     * @param unknown_type $redirect_url
     * @param unknown_type $type
     * @return string
     */
    public static function  redirect_url_add_param($redirect_url,$mark_str,$type='template',$trusteeship=false){
    	$pre_str = '';
    	if($type == 'template'){
    		$pre_str = 'template_';
    	}elseif($type == 'custom'){
    		$pre_str = 'custom_';
    	}
    	
    	// 模板客服消息，单独加参
    	$inner_order_id = '';
    	if(!$trusteeship){
    		$inner_order_id = '&inner_order_id='.$pre_str.$mark_str;
    	}
    	// 跳转链接加参
    	if(strpos($redirect_url,'?') > -1){
    		$redirect_url .= '&fromtype='.$pre_str.$mark_str.$inner_order_id;
    	}else{
    		$redirect_url .= '?fromtype='.$pre_str.$mark_str.$inner_order_id;
    	}
    	return $redirect_url;
    }
    
    // 新版要自动添加域名
    public static function  checkAddDomain($distribution_channel_id,$redirect_url){
    	// 非托管，如果url没有域名，则加上
    	if(strpos($redirect_url, 'http') !== false){
    		\Log::info('not_need_add_domain:'.$distribution_channel_id.' url:'.$redirect_url);
    	}else{
    		\Log::info('need_add_domain_before:'.$distribution_channel_id.' url:'.$redirect_url);
    		$redirect_url = env('PROTOCOL').'://site'.encodeDistributionChannelId($distribution_channel_id).'.'.env('CUSTOM_HOST').'.com'.$redirect_url;
    		\Log::info('need_add_domain_after:'.$distribution_channel_id.' url:'.$redirect_url);
    	}
    	return $redirect_url;
    }
    

}
