<?php
namespace XYCms;
use think\facade\Cache;
use GatewayClient\Gateway;
use app\bsadmin\model\Admin as AdminModel;
use app\common\model\User as UserModel;
use app\common\model\UserDevices as UserDevicesModel;
use app\common\model\PushMessage as PushMessageModel;
use app\common\model\PushMessageContent as PushMessageContentModel;
use XYCms\WechatPush;
use XYCms\SmsPush;
use XYCms\EmailPush;
use XYCms\AppPush;
class Push{
	/**
	 * 目标用户
	 */
	protected $uid=null;
	/**
	 * 要执行的操作
	 */
	protected $event='';
	/**
	 * 附加数据
	 */
	protected $Data='';
	/**
	 * 模板
	 */
	protected $tpl_alias='';
	/**
	 * 微信公众号OpenId
	 */
	protected $OpenId='';
	/**
	 * 手机号
	 */
	protected $mobile='';
	/**
	 * 邮箱
	 */
	protected $email='';
	/**
	 * APP推送标识
	 */
	protected $AppClientId='';
	/**
	 * 需要送达的客户端
	 */
	protected $client='';
	public function __construct($D)
    {
        $this->uid 			= $D['uid'];
        $this->event 		= $D['event'];
        $this->client 		= empty($D['client'])?['Pc','App','Sms','Email','Mp','Miniprogram']:$D['client'];
        $this->setWebInfo($D['data']);
    }
    protected function setWebInfo($Data)
    {
    	$webConfig=Cache::get('web');
    	$config=[];
    	foreach ($webConfig as $k => $v) {
    		$config['web'.$k]=$v;
    	}
		$this->Data=array_merge($Data,$config);
    }
	public static function send($D)
	{
		$push=new self($D);
		$push->init();
	}
	protected function init()
	{
		switch ($this->event) {
			case 'orderPaySuccess':
				$this->orderPaySuccessInit();
				break;
			case 'DeliveryResume':
			case 'InviteAnInterview':
			case 'IMMessage':
			case 'ResumeExamine':
			case 'RealNameNotice':
			case 'ComapnyVipExpire':
			case 'JobsExamine':
			case 'SendOffer':
				$this->UnifiedTemplateInit();
				break;
			case 'sendClientMsg':
				$this->sendGatewayMsg(['title'=>$this->Data['title'],'desc'=>mb_substr($this->Data['desc'],0,50)]);
				break;
			case 'sendSiteMsg':
				$this->sendSiteMsgEvent();
				break;
			case 'sendWechatMpTpl':
				$this->sendWechatMpTplEvent();
				break;
			case 'SystemWarning':
				$this->sendSystemWarning();
				break;
		}
	}
	protected function orderPaySuccessInit()
	{
		// 向前端推送支付成功事件
		$this->sendGatewayMsg(['otrade'=>$this->Data['otrade']]);
		$this->initUserNotice();
		$pay_type=['','支付宝','微信','Apple Pay','积分','权益兑换','字节跳动','百度'];
		$timeArr=[
			'create_time'	=>	empty($this->Data['create_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['create_time']),
			'update_time'	=>	empty($this->Data['update_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['update_time']),
			'cancel_time'	=>	empty($this->Data['cancel_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['cancel_time']),
			'expire_time'	=>	empty($this->Data['expire_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['expire_time']),
			'finish_time'	=>	empty($this->Data['finish_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['finish_time']),
			'pay_time'		=>	empty($this->Data['pay_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['pay_time']),
			'delete_time'	=>	empty($this->Data['delete_time'])?'':$this->date('Y-m-d H:i:s',$this->Data['delete_time']),
			'pay_type'		=>	empty($pay_type[$this->Data['pay_type']])?'':$pay_type[$this->Data['pay_type']]
		];
		$this->Data=array_merge($this->Data,$timeArr);
		$this->tpl_alias='PaySuccess';
		$tpl=$this->getWebsiteTemplate();
		if($tpl){
			// 创建站内信
			$D=[
				'request_id'=>	$this->Data['otrade'],
				'type'		=>	1,
				'title'		=>	$tpl['title'],
				'desc'		=>	$this->strReplaceAllFormData($tpl['desc']),
				'content'	=>	$this->strReplaceAllFormData($tpl['content']),
				'payload'	=>	json_encode(['action'=>$this->tpl_alias,'id'=>empty($this->Data['oid'])?'':$this->Data['oid']])
			];
			$this->createSiteMessage($D);
			// 发送APP通知
			if(in_array('App',$this->client))
				$this->sendAppPushEvent($D);
		}
		// 向公众号推送模板消息
		if(in_array('Mp',$this->client))
			$this->sendWechatMpTplEvent();
		// 发送短信
		if(in_array('Sms',$this->client))
			$this->sendSmsMessageEvent();
		// 发送邮件
		if(in_array('Email',$this->client))
			$this->sendEmailEvent();
	}
	protected function UnifiedTemplateInit()
	{
		$this->initUserNotice();
		$this->tpl_alias=$this->event;
		$tpl=$this->getWebsiteTemplate();
		if($tpl){
			// 创建站内信
			$D=[
				'request_id'=>	microtime(),
				'type'		=>	1,
				'title'		=>	$tpl['title'],
				'desc'		=>	$this->strReplaceAllFormData($tpl['desc']),
				'content'	=>	$this->strReplaceAllFormData($tpl['content']),
				'payload'	=>	json_encode(['action'=>$this->tpl_alias])
			];
			$this->createSiteMessage($D);
			// 发送APP通知
			if(in_array('App',$this->client))
				$this->sendAppPushEvent($D);
		}
		// 向公众号推送模板消息
		if(in_array('Mp',$this->client))
			$this->sendWechatMpTplEvent();
		// 发送短信
		if(in_array('Sms',$this->client))
			$this->sendSmsMessageEvent();
		// 发送邮件
		if(in_array('Email',$this->client))
			$this->sendEmailEvent();
	}
	protected function sendSystemWarning()
	{
		$this->tpl_alias=$this->event;
		$AdminNotice=Cache::get('AdminNotice');
		if(empty($AdminNotice[$this->Data['tpl']]))
			return false;
		$AdminModel=AdminModel::where('id','in',$AdminNotice[$this->Data['tpl']])->select();
		foreach ($AdminModel as $admin) {
			$this->OpenId='';
			$this->mobile='';
			$this->email='';
			// 向公众号推送模板消息
			if(in_array('Mp',$this->client)&&$admin->openid){
				$this->OpenId=$admin->openid;
				$this->sendAdminWechatMpTplEvent();
			}
			// 发送短信
			if(in_array('Sms',$this->client)&&$admin->mobile){
				$this->mobile=$admin->mobile;
				$this->sendSmsMessageEvent();
			}
			// 发送邮件
			if(in_array('Email',$this->client)&&$admin->email){
				$this->email=$admin->email;
				$this->sendEmailEvent();
			}
		}
	}
	protected function sendSiteMsgEvent()
	{
		$this->sendGatewayMsg(['title'=>$this->Data['title'],'desc'=>mb_substr($this->Data['desc'],0,50)]);
		// 创建后台发送站内信
		$D=[
			'type'		=>	0,
			'title'		=>	$this->Data['title'],
			'desc'		=>	$this->Data['desc'],
			'content'	=>	$this->Data['content']
		];
		$this->createSiteMessage($D);
	}
	protected function sendWechatMpTplEvent()
	{
		if (empty($this->OpenId))
			return false;
    	try {
    		$WechatPush=new WechatPush();
    		$WechatPush->setTpl($this->tpl_alias)
    		->setOpenid($this->OpenId)
    		->setData($this->Data)
    		->send();
    	} catch (\think\Exception $e) {
    		echo 'sendWechatMpTplEvent:'.$e->getMessage()."\n";
    	}
	}
	protected function sendAdminWechatMpTplEvent()
	{
		if (empty($this->OpenId))
			return false;
    	try {
    		$appConfig=config('app.domain_bind');
    		$bsadmin='bsadmin';
    		foreach ($appConfig as $k => $v) {
    			if($v=='bsadmin'){
    				$bsadmin=$k;
    				break;
    			}
    		}
    		$WechatPush=new WechatPush();
    		$WechatPush->setTpl($this->tpl_alias)
    		->setOpenid($this->OpenId)
    		->setData($this->Data)
    		->setUrl('http://'.$bsadmin.'.'.config('web.domain'))
    		->send();
    	} catch (\think\Exception $e) {
    		echo 'sendAdminWechatMpTplEvent:'.$e->getMessage()."\n";
    	}
	}
	protected function sendSmsMessageEvent()
	{
		if (empty($this->mobile))
			return false;
    	try {
    		$SmsPush=new SmsPush();
    		$SmsPush->setTpl($this->tpl_alias)
    		->setType('push')
    		->setMobile($this->mobile)
    		->setData($this->Data)
    		->send();
    	} catch (\think\Exception $e) {
    		echo 'sendSmsMessageEvent:'.$e->getMessage()."\n";
    	}
	}
	protected function sendEmailEvent()
	{
		if (empty($this->email))
			return false;
    	try {
    		$EmailPush=new EmailPush();
    		$EmailPush->setTpl($this->tpl_alias)
    		->setEmail($this->email)
    		->setData($this->Data)
    		->send();
    	} catch (\think\Exception $e) {
    		echo 'sendEmailEvent:'.$e->getMessage()."\n";
    	}
	}
	protected function sendAppPushEvent($D)
	{
		if (empty($this->AppClientId))
			return false;
    	try {
    		$AppPush=new AppPush();
    		$AppPush->setDevicesId($this->AppClientId)
    		->setRequestId($D['request_id'])
    		->setData($D)
    		->send();
    	} catch (\think\Exception $e) {
    		echo 'sendAppPushEvent:'.$e->getMessage()."\n";
    	}
	}
	protected function sendGatewayMsg($Data)
	{
        Gateway::$registerAddress = config('gateway_worker.registerAddress');
    	foreach ($this->client as $k => $v) {
	        Gateway::sendToGroup($v.':uid-'.$this->uid,socketMsg($this->event,$Data));
    	}
	}
	protected function createSiteMessage($D)
	{
		$PushMessageModel=new PushMessageModel;
		$PushMessageModel->uid		=	$this->uid;
		$PushMessageModel->type		=	$D['type'];
		$PushMessageModel->title	=	$D['title'];
		$PushMessageModel->desc		=	$D['desc'];
		$PushMessageModel->save();
		$PushMessageContentModel=new PushMessageContentModel;
		$PushMessageContentModel->mid=$PushMessageModel->id;
		$PushMessageContentModel->content=$D['content'];
		$PushMessageContentModel->save();
	}
	protected function initUserNotice()
	{
		$Field=[
			'user.id as uid,user.mobile,user.email',
			'user_info.nickname,user_info.role_type,user_info.score',
			'user_wx.wx_openid,user_wx.subscribe',
			'company.title as company_name,company.stitle as company_sname',
			'resume.name as resume_name',
			'user_vip.company_vip_time,user_vip.personal_vip_time,user_vip.personal_vip_level,user_vip.company_vip_level',
			'personal_vip.title as personal_vip,company_vip.title as company_vip'
		];
		$UserModel=UserModel::alias('user')->where(['user.id'=>$this->uid])
			->join('user_info user_info','user_info.uid=user.id')
			->join('user_wx user_wx','user_wx.uid=user.id','LEFT')
			->join('company company','company.uid=user.id','LEFT')
			->join('resume resume','resume.uid=user.id','LEFT')
			->join('user_vip user_vip','user_vip.uid=user.id','LEFT')
			->join('vip personal_vip','personal_vip.level=user_vip.personal_vip_level AND personal_vip.is_company=0','LEFT')
			->join('vip company_vip','company_vip.level=user_vip.company_vip_level AND company_vip.is_company=1','LEFT')
			->field(implode(',',$Field))
			->find();
		if($UserModel->personal_vip_level&&$UserModel->personal_vip_time>time()){
			$UserModel->personal_vip_time=date('Y-m-d',$UserModel->personal_vip_time);
		}else{
			$UserModel->personal_vip_time='永久';
		}
		if($UserModel->company_vip_level&&$UserModel->company_vip_time>time()){
			$UserModel->company_vip_time=date('Y-m-d',$UserModel->company_vip_time);
		}else{
			$UserModel->company_vip_time='永久';
		}
		$this->OpenId=$UserModel->subscribe?$UserModel->wx_openid:'';
		$this->mobile=$UserModel->mobile;
		$this->email=$UserModel->email;
		$UserModel->nickname=base64_decode($UserModel->nickname);
		$UserDevicesModel=UserDevicesModel::where(['uid'=>$this->uid])->order('id desc')->find();
		$this->AppClientId=$UserDevicesModel?$UserDevicesModel->devices_id:'';
		$this->Data['u']=$UserModel->toArray();
	}
	protected function date($format,$time)
	{
	    if (!is_numeric($time)) {
	        $time=strtotime($time);
	    }
	    if ($time) {
	    	return date($format,$time);
	    }else{
	    	return $time;
	    }
	}
	protected function getWebsiteTemplate()
	{
        $tpl=Cache::get('WebsiteTemplate.'.$this->tpl_alias);
    	if ($tpl&&$tpl['status']) return $tpl;
    	return false;
	}
	protected function strReplaceAllFormData($str)
	{
		foreach ($this->Data as $k => $v) {
			if(is_string($v))
			$str=str_replace('{'.$k.'}',$v,$str);
		}
		if(!empty($this->Data['u'])){
			foreach ($this->Data['u'] as $k => $v) {
				if(is_string($v))
				$str=str_replace('{u.'.$k.'}',$v,$str);
			}
		}
		return $str;
	}
}