<?php
/**
  * @method 省市区的管理
  * @author soul
  * @copyright 2016/3/31
  */
class OthPct
{
	/**
	  * @method 根据IP地址获取省市
	  * @param  ip              string [必填] IP地址
	  * @author soul
	  * @copyright 2017/8/16
	  * @return 
		{"status":true,"data":{"country":"中国","pcts":["广东省","广州市"],"pctids":["19","1901"],"lng_lat":"113.273239,23.157921"},"code":0,"runtime":73}
		{"status":false,"data":'失败原因',"code":0}
	  */
	public function getIpPCT($ip, $lngFlag = 1)
	{
		//https://github.com/zhuzhichao/ip-location-zh
		/*require_once(mvc::$cfg['AUTOLOAD']['Oth']['path'].'lib/ip/Ip.php');
		$ipres = Ip::find($ip);*/

		$ip2region = new Ip2Region();
		$ipres = $ip2region->memorySearch($ip);
		$region = explode('|', $ipres['region']);
		
		$arr = [
			'country'=>$region[0],
			'pcts'=>[],
			'pctids'=>[],
			'lng_lat'=>''
		];
		if(!empty($region[2]))
		{
			$arr['pcts'][0] = $region[2];
			if(!empty($region[3])) $arr['pcts'][1] = $region[3];
		}
		if($arr['country'] == '中国' && !empty($arr['pcts']))
		{
			$res = $this->formatAddrInfo(join('', $arr['pcts']), '', $lngFlag);
			if(!empty($res['data']['pctids']))
			{
				$arr['pcts'] = $res['data']['pcts'];
				$arr['pctids'] = $res['data']['pctids'];
				if($res['data']['lng'] && $res['data']['lat'])
					$arr['lng_lat'] = $res['data']['lng'].','.$res['data']['lat'];
			}
		}
		return LibFc::ReturnData(true, $arr);
	}
	

	/**
	  * @method 根据经纬度获取地址信息
	  * @param  $lng_lat             float [必填] 精度 Wgs84
	  * @param  $lat             float [必填] 纬度 Wgs84
	  * @author soul
	  * @copyright 2022/2/11
	  * @return {"status":true,"data":{"pctids":["19","1901","14423","14436"],"pcts":["广东省","广州市","白云区","石井街道"],"full_addr":"广东省,广州市,白云区,石井街道,潭村北社区居委会","mini_addr":"潭村北","distance":"0.6704350977314392"},"code":0,"runtime":244}
	  */
	public function getGpsInfo($lng, $lat)
	{
		$arr = [];
		/*2023/4/17 开始使用天地图
		$OthGpsConvert = new OthGpsConvert();
		$gspres = $OthGpsConvert->wgs84ToBd09($lng, $lat);
		$lng = $gspres['longitude'];
		$lat = $gspres['latitude'];*/
		$YpwBase = new YpwBase();
		$table = 'yp_province_gps';
		$filed = ['"" pctids','"" pcts','pg_pc_id pc_id','pg_addr full_addr', 'pg_simple mini_addr', '"0" as distance'];
		//$filed[] = sprintf('(6371*ACOS(COS(RADIANS(%f))*COS(RADIANS(pg_lat))*COS(RADIANS(pg_lng)-RADIANS(%f))+SIN(RADIANS(%f))*SIN(RADIANS(pg_lat)))) AS distance', $lat, $lng, $lat);
		//$res = $YpwBase->get($table, $filed, sprintf(' and pg_lng < %f and pg_lng > %f and pg_lat < %f and pg_lat > %f order by distance limit 1', $lng+1, $lng-1, $lat+1, $lat-1), true);
		$res = $YpwBase->get($table, $filed, sprintf(' and pg_lng < %f and pg_lng > %f and pg_lat < %f and pg_lat > %f ORDER BY ABS(ABS(pg_lng-%f) + ABS(pg_lat-%f)) limit 1', $lng+0.5, $lng-0.5, $lat+0.5, $lat-0.5, $lng, $lat), true);
		if(!empty($res['data']))
		{
			$arr = $res['data'];
			$res = $YpwBase->get('yp_province_city', ['concat(pc_path,",",pc_id) pctids','pc_name_des pcts'], sprintf(' and pc_id =%d limit 1', $arr['pc_id']), true);
			if(!empty($res['data']))
			{
				$arr = array_merge($arr, $res['data']);
				$arr['pctids'] = explode(',', ltrim($arr['pctids'], '0,'));
				$arr['pcts'] = explode(',', $arr['pcts']);
			}
			//地址最后一个
			$arr['full_addr'] = explode(',', $arr['full_addr']);
			array_pop($arr['full_addr']);
			$arr['full_addr'][] = $arr['mini_addr'];
			$arr['full_addr'] = implode(',', $arr['full_addr']);
		}
		return LibFc::ReturnData(true, $arr);
	}


	/**
	  * @method 省市区缓存
	  * @param  cache    bool [选填] true|false
	  * @author soul
	  * @copyright 2017/8/16
	  * @return 
	  */
	public function getPctCache($cache = true)
	{
		$arr = ['pcts'=>[], 'tree'=>[]];
		$file = mvc::$cfg['AUTOLOAD']['Oth']['path'].'cache/allPct.php';
		if(1|| !file_exists($file) || !$cache)
		{
			$YpwBase = new YpwBase();
			$res = $YpwBase->Get('yp_province_city', ['pc_id, pc_pid, pc_path, pc_name'], " and (LENGTH(pc_path) - LENGTH(REPLACE(pc_path, ',', ''))) < 3");
			$pctArr = array_column($res['data'], null, 'pc_id');
			foreach($pctArr as $v)
			{
				$v['pc_path'] = explode(',', $v['pc_path'].','.$v['pc_id']);
				array_shift($v['pc_path']);
				$v['names'] = '';
				foreach($v['pc_path'] as $vv)
				{
					$v['names'] .= $pctArr[$vv]['pc_name'];
				}
				$v['pc_path'] = implode(',', $v['pc_path']);
				$arr['pcts'][$v['pc_id']] = $v;
				$arr['tree'][$v['pc_pid']][] = $v['pc_id'];
			}
			LibFc::ArraySave($arr, $file);
		}
		else
		{//括起来为了防止读取文件失败
			$arr = include($file);
		}
		return LibFc::ReturnData(true, $arr);
	}

	/**
	  * @method 格式化地址，匹配出省市区、经纬度
	  * @param  addr    string [必填] 龙华新村鹊山路口太阳能硅谷1003
	  * @param  pctIds    string [选填] 已有的省市区ID 19,1901,14363
	  * @param  lngFlag    int [选填] 是否需要返回经纬度 1|0
	  * @author soul
	  * @copyright 2017/8/16
	  * @return 
	  */
	public function formatAddrInfo($addr, $pctIds = '', $lngFlag = 1)
	{
		$res = $this->getPctCache();
		$allPctArr = $res['data'];
		$arr = ['pctids'=>[], 'pcts'=>[], 'new'=>$addr, 'full'=>$addr, 'lng'=>0, 'lat'=>0];
		if(empty($pctIds))
		{
			//确定省 '新疆维吾尔自治区乌鲁木齐市新市区百园路9号';
			foreach($allPctArr['tree'][0] as $id)
			{
				$sname = $allPctArr['pcts'][$id]['pc_name'];
				//省
				if(stripos($arr['new'], $sname) === 0)
				{
					$arr['pctids'][] = $id;
					$arr['new'] = substr($arr['new'], strlen($sname));
					//北京 天津 特殊
					if(stripos($arr['new'], '市') === 0) $arr['new'] = $addr;
					
					//自治区
					if(stripos($arr['new'], '自治区') !== false)
					{
						$arr['new'] = substr($arr['new'], stripos($arr['new'], '自治区')+strlen('自治区'));
					}
				}
				
				//辽宁大连甘井子区泡崖8区106号
				if(empty($arr['pctids']) && stripos($sname, '省'))
				{
					$sname = substr($sname, 0, stripos($sname, '省'));
					if(stripos($arr['new'], $sname) === 0)
					{
						$arr['pctids'][] = $id;
						$arr['new'] = substr($arr['new'], strlen($sname));
					}
				}
				if(!empty($arr['pctids'])) break;
			}
			
			//通过城市反查省
			if(empty($arr['pctids']))
			{
				$matchPids = [];
				foreach($allPctArr['tree'][0] as $pid)
				{
					if(!is_array($allPctArr['tree'][$pid])) continue;
					foreach($allPctArr['tree'][$pid] as $cid)
					{
						$sname = $allPctArr['pcts'][$cid]['pc_name'];
						if(stripos($arr['new'], $sname) === 0 || stripos($arr['new'], substr($sname, 0, stripos($sname, '市'))) === 0)
						{
							$matchPids[] = $pid;
						}
					}
				}
				//有且只有一个省
				$matchPids = array_unique($matchPids);
				if(count($matchPids) == 1)
				{
					$arr['pctids'][] = $matchPids[0];
				}
			}
			$arr['new'] = trim($arr['new']);

			//确定市
			if(!empty($arr['pctids'][0]) && !empty($allPctArr['tree'][$arr['pctids'][0]]))
			{
				foreach($allPctArr['tree'][$arr['pctids'][0]] as $id)
				{
					$sname = $allPctArr['pcts'][$id]['pc_name'];
					if(stripos($arr['new'], $sname) === 0)
					{
						$arr['pctids'][] = $id;
						$arr['new'] = substr($arr['new'], strlen($sname));
						//市辖区
						if(stripos($arr['new'], '市辖区') !== false)
						{
							$arr['new'] = substr($arr['new'], stripos($arr['new'], '市辖区')+strlen('市辖区'));
						}
					}

					if(empty($arr['pctids'][1]) && stripos($sname, '市'))
					{
						$sname = substr($sname, 0, stripos($sname, '市'));
						if(stripos($arr['new'], $sname) === 0)
						{
							$arr['pctids'][] = $id;
							$arr['new'] = substr($arr['new'], strlen($sname));
						}
					}
					if(!empty($arr['pctids'][1])) break;
				}
				//北京、重庆...
				if(empty($arr['pctids'][1]) && count($allPctArr['tree'][$arr['pctids'][0]]) == 1)
				{
					$arr['pctids'][] = $allPctArr['tree'][$arr['pctids'][0]][0];
				}
			}
			$arr['new'] = trim($arr['new']);
			
			//确定镇区
			if(!empty($arr['pctids'][1]) && !empty($allPctArr['tree'][$arr['pctids'][1]]))
			{
				foreach($allPctArr['tree'][$arr['pctids'][1]] as $id)
				{
					if(stripos($arr['new'], $allPctArr['pcts'][$id]['pc_name']) === 0)
					{
						$arr['pctids'][] = $id;
						$arr['new'] = substr($arr['new'], strlen($allPctArr['pcts'][$id]['pc_name']));
					}
				}
			}
			$arr['new'] = trim($arr['new']);
		}
		else
		{
			$arr['pctids'] = explode(',', $pctIds);
		}
		$endPcId = 0;
		foreach($arr['pctids'] as $id)
		{
			$arr['pcts'][] = $allPctArr['pcts'][$id]['pc_name'];
			$endPcId = $id;
		}
		$arr['full'] = implode('', $arr['pcts']).$arr['new'];
		if($lngFlag && count($arr['pctids']) >= 2 )
		{
			$lngLatArr = [];
			$tempArr = [];
			//省市区的地址
			$YpwBase = new YpwBase();
			$res = $YpwBase->Get('yp_province_city', ['pc_lng lng', 'pc_lat lat'], sprintf(" and pc_id=%d and pc_lng > 0", $endPcId), true);
			if(!empty($res['data']))
			{
				$lngLatArr[] = $res['data'];
			}
			else
			{//省市区无定位
				$tempArr[] = implode('', $arr['pcts']);
			}
			//有详细地址
			if(!empty($arr['new'])) $tempArr[] = $arr['full'];

			foreach($tempArr as $addr)
			{
				$res = $this->getLngLat($addr);
				if($res['data']['lng'] && $res['data']['lat'])
				{
					$lngLatArr[] = $res['data'];
				}
			}
			//省市区和地址的经纬度相差太大则忽略
			if(count($lngLatArr) == 2 && ceil($lngLatArr[0]['lng'] - $lngLatArr[1]['lng']) <= 4 && ceil($lngLatArr[0]['lat'] - $lngLatArr[1]['lat']) <= 4)
			{
				$arr['lng'] = $lngLatArr[1]['lng'];
				$arr['lat'] = $lngLatArr[1]['lat'];
			}else if(count($lngLatArr) == 1 && $lngLatArr[0]['lng']) {
				$arr['lng'] = $lngLatArr[0]['lng'];
				$arr['lat'] = $lngLatArr[0]['lat'];
			}
		}
		return LibFc::ReturnData(true, $arr);
	}

	/**
	  * @method 获取地址的经纬度信息
	  * @param  $addr   [必填] 地址
	  * @author soul
	  * @copyright 2022/2/11
	  * @return {"status":true,"data":{"pctids":["19","1901","14423","14436"],"pcts":["广东省","广州市","白云区","石井街道"],"full_addr":"广东省,广州市,白云区,石井街道,潭村北社区居委会","mini_addr":"潭村北","distance":"0.6704350977314392"},"code":0,"runtime":244}
	  */
	public function getLngLat($addr, $run = 0)
	{
		$arr = ['lng'=>0, 'lat'=>0];
		$url = 'http://api.tianditu.gov.cn/geocoder?ds='.urlencode('{"keyWord":"'.(strtr($addr, ['（'=>'(', '）'=>')', '：'=>''])).'"}').'&tk='.mvc::$cfg['MAPTIANDI']['AK_KEY'];
		//{"msg":"ok","location":{"score":95,"level":"门址","lon":113.234730000389,"lat":23.1909100003962,"keyWord":"广州市白云区石槎路363号长盛服装大厦A栋"},"searchVersion":"6.4.6V","status":"0"}
		$curl = curl_init();
		curl_setopt_array($curl, [
		  CURLOPT_URL => $url,
		  CURLOPT_RETURNTRANSFER => true,
		  CURLOPT_ENCODING => '',
		  CURLOPT_MAXREDIRS => 10,
		  CURLOPT_TIMEOUT => 2,
		  CURLOPT_FOLLOWLOCATION => true,
		  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
		  CURLOPT_CUSTOMREQUEST => 'GET'
		]);
		$html = curl_exec($curl);
		curl_close($curl);
		$run++;
		$tArr = json_decode($html, true);
		if(is_array($tArr) && !empty($tArr['location']['lon'])){
			$arr = ['lng'=>sprintf("%.6f",$tArr['location']['lon']), 'lat'=>sprintf("%.6f", $tArr['location']['lat'])];
		}/*else if(stripos($html, '无结果') === false){
			return LibFc::ReturnData(false, '经纬度API异常，请稍后重试！'.$html);
		}*/
		return LibFc::ReturnData(true, $arr);
	}


	/**
	  * @method 获取手机号码信息
	  * @param  $mobile   [必填] 手机号
	  * @author soul
	  * @copyright 2023/3/29
	  * @return {"status":true,"data":{"pctids":["19","1901"],"pcts":["广东省","广州市"],"new":"","full":"广东省广州市","lng":0,"lat":0,"type":"移动","quhao":"020"},"code":0,"runtime":73}
	  */
	public function getMobileInfo($mobile)
	{
		$mobile = preg_replace('/[^0-9]/', '', $mobile);
		$arr = [];
		if(strlen($mobile) != 11) return LibFc::ReturnData(true, $arr);
		$YpwBase = new YpwBase();
		$res = $YpwBase->Get('yp_mobile_info', ['ymi_format','ymi_info','ymi_etime'], sprintf(" and ymi_mobile = '%s'", $mobile), true);
		$hasArr = [];
		if(!empty($res['data']))
		{
			$hasArr = $res['data'];
			$info = json_decode($hasArr['ymi_info'], true);
			$format = json_decode($hasArr['ymi_format'], true);
			if(time() - $hasArr['ymi_etime'] < 3600*24*60 && !empty($format['pctids']))
				return LibFc::ReturnData(true, $format);
		}
		else
		{
			$url = 'https://api.ip138.com/mobile/?mobile='.$mobile.'&datatype=jsonp';
			$header = ['token:'.mvc::$cfg['IP138']['mobile']];
			$ch = curl_init();  
			curl_setopt($ch,CURLOPT_URL,$url);
			curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
			curl_setopt($ch,CURLOPT_HTTPHEADER,$header); 
			curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);  
			curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,3);  
			$html = curl_exec($ch);
			curl_close($ch);
			$htmlArr = json_decode($html, true);
			if(is_array($htmlArr) && $htmlArr['ret'] == 'ok' && !empty($htmlArr['data']))
			{
				$info = $htmlArr;
			}
		}
		if(!empty($info['data'][0]))
		{//省市区实时匹配
			$res = $this->formatAddrInfo($info['data'][0].$info['data'][1], '', 0);
			$format = $res['data'];
			$format['type'] = $info['data'][2];
			$format['quhao'] = $info['data'][3];
			$addArr = ['ymi_format'=>json_encode($format, JSON_UNESCAPED_UNICODE), 'ymi_etime'=>time()];
			if(!empty($hasArr)){
				$YpwBase->Set('yp_mobile_info', $addArr, sprintf(" and ymi_mobile = '%s'", $mobile));
			}else{
				$addArr['ymi_info'] = json_encode($info, JSON_UNESCAPED_UNICODE);
				$addArr['ymi_mobile'] = $mobile;
				$YpwBase->Add('yp_mobile_info', $addArr);
			}
		}
		return LibFc::ReturnData(true, $format);
	}

	public function curl($url)
	{
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_TIMEOUT, 10);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
		curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,3);
		$result = curl_exec($ch);
		return $result;
	}
}