<?php
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/umengApi.class.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/android/AndroidBroadcast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/android/AndroidFilecast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/android/AndroidGroupcast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/android/AndroidUnicast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/android/AndroidCustomizedcast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/ios/IOSBroadcast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/ios/IOSFilecast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/ios/IOSGroupcast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/ios/IOSUnicast.php');
require_once(mvc::$cfg['AUTOLOAD']['Pjl']['path'].'lib/umeng/notification/ios/IOSCustomizedcast.php');

/**
  * @method 跑街令 消息推送
  * @author soul
  * @copyright 2019/5/8
  */
class PjlTs extends PjlBase
{
	/**
	  * @method 添加推送设备
	  * @param  $dataArr =[
				'de_style'=>sdk类型 umeng,huawei,xiaomi
				'de_device'=>sdk生成的设备唯一识别ID   如 qq的device_token
				'de_make'=>手机的生产商 华为、小米、苹果...
			]
	  * @author soul
	  * @copyright 2019/5/8
	  * @return {"status":true,"data": 设备编码ID,"code":0}
	  */
	public function updateDevice($dataArr)
	{
		$styleArr = ['umeng','huawei','xiaomi'];
		if(empty($dataArr['de_style']) || !in_array($dataArr['de_style'], $styleArr) ) return LibFc::ReturnData(false, '消息推送的sdk类型de_style不正确！');
		if(empty($dataArr['de_device'])) return LibFc::ReturnData(false, '消息推送的设备编码de_device不能为空！');
		if(empty($dataArr['de_make'])) return LibFc::ReturnData(false, '消息推送的de_make不能为空！');

		$dataArr['de_make'] = strtolower($dataArr['de_make']);
		switch($dataArr['de_make'])
		{
			case '小米': $dataArr['de_make'] = 'xiaomi'; break;
			case '华为': $dataArr['de_make'] = 'huawei'; break;
			case '苹果':
			case 'apple':
				$dataArr['de_sys'] = 'ios';
				$dataArr['de_make'] = 'apple'; 
			break;
		}
		
		$dataArr['de_device'] = strlen($dataArr['de_device']) > 128 ? substr($dataArr['de_device'], 0, 128) : $dataArr['de_device'];
		$dataArr['de_sys'] = empty($dataArr['de_sys']) || $dataArr['de_sys'] != 'ios'? 'android': 'ios';
		$where = sprintf(" and de_style='%s' and de_device='%s' limit 1", LibFc::Escape($dataArr['de_style']), LibFc::Escape($dataArr['de_device']));
		$res = $this->get('ts_device', ['de_id'], $where, true);
		if(isset($dataArr['de_uid'])) $dataArr['de_uid'] = (int) $dataArr['de_uid'];
		if(!empty($res['data']))
		{
			$dataArr['de_id'] = $res['data']['de_id'];
			unset($dataArr['de_atime']);
			$this->set('ts_device', $dataArr, sprintf(" and de_id=%d", $dataArr['de_id']));
		}
		else
		{
			$dataArr['de_atime'] = time();
			$res = $this->add('ts_device', $dataArr);
			$dataArr['de_id'] = $res['data'];
		}
		return LibFc::ReturnData(true, $dataArr['de_id']);
	}



	/**
	  * @method 推送消息
	  * @param  style  string [选填] 所有客户端:all  自定义:slef  配件商:shop  人脉:renmai  报价者(已填品牌的用户):offer  所有会员:alluser  非注册用户：notuser
	  * @param  msg	   string [必填] 推送内容	
	  * @param  title  string [必填] 通知标题
	  * @param  deidArr array [选填] 设备ID列表 提供了style 不用填写，否则必填
	  * @param  othArr array [选填] [
									'thi_user'=>'发布人',
									'thi_u_id'=>'发布人ID',
									...
								  ]
	  * @author soul
	  * @copyright 2019/5/8
	  * @return {"status":true,"data": [11,22] ,"code":0}
	  */
	public function push($style, $msg, $title, $deidArr = [], $othArr = [])
	{
		$sendMode = "true";
		foreach($deidArr as $k=>$v)
		{
			$deidArr[$k] = (int) $v; 
		}
		if(empty($msg)) return LibFc::ReturnData(false, '推送的内容不能为空！');
		
		$sysArr = ['android', 'ios'];
		$deFile = ['de_id', 'de_device', 'de_sys'];
		$deviceArr = [];
		$othArr['thi_style_param'] = empty($othArr['thi_style_param']) && !is_array($othArr['thi_style_param'])? []: $othArr['thi_style_param'];
		$uidArr = [];
		switch($style)
		{
			case 'user':
				$table = 'ts_device JOIN pl_user ON pu_uid = de_uid';
				$where = ' and de_uid > 0';
				//配件商
				
				if(isset($othArr['thi_style_param']['has_shop']) && trim($othArr['thi_style_param']['has_shop']) != '')
				{
					if($othArr['thi_style_param']['has_shop'] == 1)
					{
						$table .= ' JOIN pl_shop ON shop_id=de_uid';
					}
					else if($othArr['thi_style_param']['has_shop'] == 0)
					{
						$table .= ' LEFT JOIN pl_shop ON shop_id=de_uid and shop_id is null';
					}
				}
				//企业类型
				if(!empty($othArr['thi_style_param']['pu_work_style']))
				{
					$tvArr = [];
					foreach($othArr['thi_style_param']['pu_work_style'] as $tv)
					{
						$tvArr[]  = LibFc::Escape($tv);
					}
					$where .= sprintf(" and pu_work_style in ('%s')", implode("','", array_unique($tvArr)));
				}

				//经营类别
				if(!empty($othArr['thi_style_param']['pu_pro_style']) && !in_array('全车件', $othArr['thi_style_param']['pu_pro_style']))
				{
					$tvArr = [];
					foreach($othArr['thi_style_param']['pu_pro_style'] as $tv)
					{
						$tvArr[]  = LibFc::Escape($tv);
					}
					$where .= sprintf(" and (pu_pro_style in ('%s') OR pu_pro_style ='全车件')", implode("','", array_unique($tvArr)));
				}
				
				//经营品牌
				if(!empty($othArr['thi_style_param']['brands']))
				{
					$tvArr = [];
					foreach(explode(',', $othArr['thi_style_param']['brands']) as $tv)
					{
						$tvArr[]  = (int) $tv;
					}
					$table .= ' LEFT JOIN pl_user_brand ON ub_pu_id=pu_uid';
					$where .= sprintf(" and (ub_brand_id in ('%s') OR pu_all_brands =1)", implode(",", array_unique($tvArr)));
				}
				$deres = $this->get($table, $deFile, $where.' group by de_id');
			break;
			case 'username':
				if(!empty($othArr['thi_style_param']['username']))
				{
					$userArr = [];
					foreach(explode(',', $othArr['thi_style_param']['username']) as $v)
					{
						$userArr[] = $v; 
					}
					$userArr = array_unique($userArr);
					$YpwBase = new YpwBase();
					$res = $YpwBase->Get('yp_user', ['u_id'], sprintf(" and u_name in ('%s')", implode("','", $userArr)));
					$uidArr = array_column($res['data'], 'u_id');
					if(!empty($uidArr))
					{	
						$deres = $this->get('ts_device', $deFile, sprintf(" and de_uid in (%s)", implode(',', $uidArr)));
					}
				}
				if(empty($deres['data']))
					return LibFc::ReturnData(false, '填写的宜配账号无法匹配到客户端，推送失败！');
			break;
			case 'notuser':
				$deres = $this->get('ts_device', $deFile, " and de_uid = 0");
			break;
			case 'self':
				$deres = $this->get('ts_device', $deFile, sprintf(" and de_id in (%s)", implode(',', $deidArr)));
			break;
		}
		$othArr['thi_style_param'] = json_encode($othArr['thi_style_param']);
		if(!empty($deres['data']))
		{
			foreach($deres['data'] as $v)
			{
				$deviceArr[$v['de_sys']]['devices'][] = $v['de_device'];
				$deviceArr[$v['de_sys']]['ids'][] = $v['de_id'];
			}
		}

		if($style != 'all' && empty($deviceArr)) return LibFc::ReturnData(false, '无法匹配到推送客户端，推送失败！');
		$thi_ids = [];
		switch($style)
		{
			case 'all':
				foreach($sysArr as $sys)
				{
					//安卓
					$pushCfg = mvc::$cfg['PUSH']['umeng'][$sys];
					$pushObj = $sys == 'ios'? new IOSBroadcast() : new AndroidBroadcast();
					$pushObj->setAppMasterSecret($pushCfg['masterSecret']);
					$pushObj->setPredefinedKeyValue("appkey", $pushCfg['key']);
					$pushObj->setPredefinedKeyValue("timestamp", strval(time()));
					if($sys == 'ios')
					{
						$a = ["title"=>$title,"subtitle"=>$title,"body"=>$msg];              
						$pushObj->setPredefinedKeyValue("alert", json_encode($a));
						$pushObj->setPredefinedKeyValue("badge", 0);
						$pushObj->setPredefinedKeyValue("sound", "chime");
					}
					else
					{
						$pushObj->setPredefinedKeyValue("ticker", $title);
						$pushObj->setPredefinedKeyValue("title", $title);
						$pushObj->setPredefinedKeyValue("text", $msg);
						$pushObj->setPredefinedKeyValue("after_open", "go_app");
					}
					// 可选，正式/测试模式。默认为true
					$pushObj->setPredefinedKeyValue("production_mode", $sendMode);
					if(isset($othArr['thi_btime']) && $othArr['thi_btime'] > time())
						$pushObj->setPredefinedKeyValue("start_time", date('Y-m-d H:i:s', $othArr['thi_btime']));
					$res = $pushObj->send();
					if(!empty($res['ret']) && $res['ret'] == 'SUCCESS')
					{
						//入库
						$addArr = [
							'thi_status'=>0,
							'thi_style'=>$style,
							'thi_style_param'=>$othArr['thi_style_param'],
							'thi_title'=>$title,	
							'thi_txt'=>$msg,	
							'thi_type'=>1,
							'thi_sys'=>$sys,
							'thi_atime'=>time(),
							'thi_push_id'=>$res['data']['task_id']
						];
						if(isset($othArr['thi_user'])) $addArr['thi_user'] = $othArr['thi_user'];
						if(isset($othArr['thi_u_id'])) $addArr['thi_u_id'] = (int) $othArr['thi_u_id'];
						if(isset($othArr['thi_btime']) && $othArr['thi_btime'] > time()) $addArr['thi_btime'] = (int) $othArr['thi_btime'];
						$res = $this->add('ts_history', $addArr);
						$thi_ids[] = $res['data'];
					}
					else
					{
						return LibFc::ReturnData(false, '推送'.$sys.'失败！');
					}
				}
			break;
			default:
				foreach($deviceArr as $sys=>$val)
				{
					$pushCfg = mvc::$cfg['PUSH']['umeng'][$sys];
					//if(count($val['devices']) == 1)
					//单播消息无法撤销，暂时不考虑单播
					if(0 == 1)
					{
						$pushObj = $sys == 'ios'? new IOSUnicast() : new AndroidUnicast();
						$pushObj->setAppMasterSecret($pushCfg['masterSecret']);
						$pushObj->setPredefinedKeyValue("appkey", $pushCfg['key']);
						$pushObj->setPredefinedKeyValue("timestamp", strval(time()));
						$pushObj->setPredefinedKeyValue("device_tokens", implode(',', $val['devices'])); 
					}
					else
					{
						$pushObj = $sys == 'ios'? new IOSFilecast() : new AndroidFilecast();
						$pushObj->setAppMasterSecret($pushCfg['masterSecret']);
						$pushObj->setPredefinedKeyValue("appkey", $pushCfg['key']);
						$pushObj->setPredefinedKeyValue("timestamp", strval(time()));
						$pushObj->uploadContents(implode("\n", $val['devices']));
					}
					
					if($sys == 'ios')
					{
						$a = ["title"=>$title,"subtitle"=>$title,"body"=>$msg];              
						$pushObj->setPredefinedKeyValue("alert", json_encode($a));
						$pushObj->setPredefinedKeyValue("badge", 0);
						$pushObj->setPredefinedKeyValue("sound", "chime");
					}
					else
					{
						$pushObj->setPredefinedKeyValue("ticker", $title);
						$pushObj->setPredefinedKeyValue("title", $title);
						$pushObj->setPredefinedKeyValue("text", $msg);
						$pushObj->setPredefinedKeyValue("after_open", "go_app");
					}
					// 可选，正式/测试模式。默认为true
					$pushObj->setPredefinedKeyValue("production_mode", $sendMode);
					if(isset($othArr['thi_btime']) && $othArr['thi_btime'] > time())
						$pushObj->setPredefinedKeyValue("start_time", date('Y-m-d H:i:s', $othArr['thi_btime']));
					$res = $pushObj->send();
					if(!empty($res['ret']) && $res['ret'] == 'SUCCESS')
					{
						$addArr = [
							'thi_status'=>0,	
							'thi_style'=>$style,
							'thi_style_param'=>$othArr['thi_style_param'],
							'thi_title'=>$title,	
							'thi_txt'=>$msg,	
							'thi_type'=>1,
							'thi_sys'=>$sys,
							'thi_de_ids'=>implode(',', $val['ids']),
							'thi_de_count'=>count($val['ids']),
							'thi_atime'=>time(),
							'thi_push_id'=>!empty($res['data']['task_id'])? $res['data']['task_id']: $res['data']['msg_id']
						];
						if(isset($othArr['thi_user'])) $addArr['thi_user'] = $othArr['thi_user'];
						if(isset($othArr['thi_u_id'])) $addArr['thi_u_id'] = (int) $othArr['thi_u_id'];
						if(isset($othArr['thi_btime']) && $othArr['thi_btime'] > time()) $addArr['thi_btime'] = (int) $othArr['thi_btime'];
						$res = $this->add('ts_history', $addArr);
						$thi_ids[] = $res['data'];
					}
					else
					{
						return LibFc::ReturnData(false, '推送'.$sys.'失败！');
					}
				}
			break;
		}
		if(!empty($uidArr))
		{
			$OthIm = new OthIm();
			$OthIm->sendImSysNotice($uidArr, $msg, 'im');
		}
		return LibFc::ReturnData(true, $thi_ids);
	}

	
	/**
	  * @method 取消或者删除推送
	  * @param  thi_id	   string [必填] 推送ID
	  * @param  del  string [选填] 默认不删除 true|false
	  * @copyright 2019/5/8
	  * @return {"status":true,"data": true ,"code":0}
	  */
	function closePush($thi_id, $del = false)
	{
		$res = $this->get('ts_history', ['thi_id', 'thi_status', 'thi_sys', 'thi_push_id'], sprintf(" and thi_id=%d", $thi_id), true);
		if(!empty($res['data']))
		{
			$thiArr = $res['data'];
			$pushCfg = mvc::$cfg['PUSH']['umeng'][$thiArr['thi_sys']];
			$umengApi = new umengApi($pushCfg['key'], $pushCfg['masterSecret']);
			$umengApi->setPredefinedKeyValue("task_id", $thiArr['thi_push_id']);
			$umengApi->get('/api/cancel');
			if(!empty($del))
			{
				$this->del('ts_history', sprintf(" and thi_id=%d", $thiArr['thi_id']));
			}
			else
			{
				$this->set('ts_history', ['thi_status'=>-2], sprintf(" and thi_id=%d", $thiArr['thi_id']));
			}
		}
		return LibFc::ReturnData(true);
	}

	/**
	  * @method 更新推送的状态
	  * @copyright 2019/5/8
	  * @return {"status":true,"data": true ,"code":0}
	  */
	function checkPushStatus()
	{
		$res = $this->get('ts_history', ['thi_id', 'thi_status', 'thi_sys', 'thi_push_id'], " and thi_status=0 and thi_push_id != ''");
		foreach($res['data'] as $v)
		{
			$pushCfg = mvc::$cfg['PUSH']['umeng'][$v['thi_sys']];
			$umengApi = new umengApi($pushCfg['key'], $pushCfg['masterSecret']);
			$umengApi->setPredefinedKeyValue("task_id", $v['thi_push_id']);
			$res = $umengApi->get('/api/status');
			if(!empty($res['status']))
			{	
				$setArr = ['thi_result'=>json_encode($res)];
				// 消息状态: 0-排队中, 1-发送中，2-发送完成，3-发送失败，4-消息被撤销， 5-消息过期, 6-筛选结果为空，7-定时任务尚未开始处理
				if($res['data']['status'] == 2) $setArr['thi_status'] = 1;
				if($res['data']['status'] == 3) $setArr['thi_status'] = -1;
				if(in_array($res['data']['status'], [4,5,6])){
					$setArr['thi_status'] = -2;
					$setArr['thi_stime'] = time();
				}
				$this->set('ts_history', $setArr, sprintf(" and thi_id=%d", $v['thi_id']));
			}
		}
		return LibFc::ReturnData(true);
	
	}
}