<?php
/**
* 留存相关
*/
defined('IN_WEB') or die('Include Error!');
include_once dirname(__FILE__) . "/Base.php";
class Remain extends Base
{
	private $_sidList = [];

	/**
	*	留存首页
	*/
	public function index($param)
	{
		$stime = oo::functions()->uint($param['stime']);
		$etime = oo::functions()->uint($param['etime']);
		$isCache = oo::functions()->uint($param['isCache']);
        $sidList = json_decode($param['sidList'], 1);
        if(empty($sidList)) {
            return json_encode([]);
        }
        $this->_sidList = $sidList;
        $cacheKey = okeys::keydata('REMAIN');
        $isAllSid = $this->isAllSid($sidList);
        if($isAllSid) {
            if($isCache == 1) {
                $keydataInfo = oo::commonOprRedis('common')->get($cacheKey);
                if(!empty($keydataInfo)){
                    return $keydataInfo;
                }
            }
        }

		$daysList = $this->getDays($stime, $etime, 2);
		$data['daylist'] = $daysList;
		$day1Remain = $day3Remain = $day7Remain = $day1ActRemain = $day3ActRemain = $day7ActRemain = array();
		foreach ($daysList as $day) {//此处已经减少了一天
			$days1ago = $day;
			$days2ago = date('Ymd', strtotime($day.'-1 day'));
			$days3age = date('Ymd', strtotime($day.'-3 days'));
			$days8age = date('Ymd', strtotime($day.'-7 days'));
			$days15age = date('Ymd', strtotime($day.'-15 days'));
			$days30age = date('Ymd', strtotime($day.'-30 days'));//30天没数据，先按29天的算
//			$days30age = date('Ymd', strtotime($day.'-20 days'));
			$days60age = date('Ymd', strtotime($day.'-60 days'));

            ////次日新增留存 比如今天29号 就计算28号的次日留存 那么新增玩家从27号算,
			$yesterdayPlayer = $this->getAllPlayer($days1ago, 2);//登陆玩家
			$last2daysPlayer = $this->getAllPlayer($days2ago, 1);//新增玩家
			$intersect1dayPlay = array_intersect($yesterdayPlayer, $last2daysPlayer);//交集玩家
			$tempDay1Remain = empty(count($last2daysPlayer)) ? 0 : count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
			$data['day1Remain'][] = round($tempDay1Remain, 4)*100;//次日留存率
			//$data['day1Remain'][] = count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率

			//3日新增留存
			$last3daysPlayer = $this->getAllPlayer($days3age, 1);//新增玩家
			$intersect3dayPlay = array_intersect($yesterdayPlayer, $last3daysPlayer);//交集玩家
			//$data['day3Remain'][] = count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
			$tday3Remain = empty(count($last3daysPlayer)) ? 0 :  count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
			$data['day3Remain'][] = round($tday3Remain, 4)*100;//3日留存率

			//7日新增留存
			$last8daysPlayer = $this->getAllPlayer($days8age, 1);//新增玩家
			$intersect8dayPlay = array_intersect($yesterdayPlayer, $last8daysPlayer);//交集玩家
			$data['day7Remain'][] = empty(count($last8daysPlayer)) ? 0 : round( count($intersect8dayPlay) / count($last8daysPlayer), 4 )*100;//3日留存率
			
			//15日新增留存
			$last15daysPlayer = $this->getAllPlayer($days15age, 1);//新增玩家
			$intersect15dayPlay = array_intersect($yesterdayPlayer, $last15daysPlayer);//交集玩家
			$data['day15Remain'][] = empty(count($last15daysPlayer)) ? 0 : round( count($intersect15dayPlay) / count($last15daysPlayer), 4 )*100;//15日留存率

            //30日新增留存
            $last30daysPlay = $this->getAllPlayer($days30age, 1);//30天新增玩家
            $intersect30dayPlay = array_intersect($yesterdayPlayer, $last30daysPlay); //交集玩家
//            oo::logs()->debug3(array('$last30daysPlay' => $last30daysPlay, '$intersect30dayPlay' => $intersect30dayPlay), 'Keydata.php');
            $data['day30Remain'][] = empty(count($last30daysPlay)) ? 0 : round(count($intersect30dayPlay) / count($last30daysPlay), 4) * 100;//30日留存率
			
			//60日新增留存
			$last60daysPlayer = $this->getAllPlayer($days60age, 1);//新增玩家
			$intersect60dayPlay = array_intersect($yesterdayPlayer, $last60daysPlayer);//交集玩家
			$data['day60Remain'][] = empty(count($last60daysPlayer)) ? 0 : round( count($intersect60dayPlay) / count($last60daysPlayer), 4 )*100;//60日留存率

			//次日活跃留存
			$yesterdayLoginPlayer = $this->getAllPlayer($days1ago, 2);//登陆玩家
			$last2daysLoginPlayer = $this->getAllPlayer($days2ago, 2);//登陆玩家
			$intersect1dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last2daysLoginPlayer);//交集玩家
			$data['day1ActRemain'][] = empty(count($last2daysLoginPlayer)) ? 0 : round( count($intersect1dayLoginPlay) / count($last2daysLoginPlayer), 4 )*100;//次日留存率

			//3日活跃留存
			$last3daysLoginPlayer = $this->getAllPlayer($days3age, 2);//登陆玩家
			$intersect3dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last3daysLoginPlayer);//交集玩家
			$data['day3ActRemain'][] = empty(count($last3daysLoginPlayer)) ? 0 : round(count( $intersect3dayLoginPlay) / count($last3daysLoginPlayer), 4 )*100;//3日留存率

			//7日活跃留存
			$last8daysLoginPlayer = $this->getAllPlayer($days8age, 2);//登陆玩家
			$intersect8dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last8daysLoginPlayer);//交集玩家
			$data['day7ActRemain'][] = empty(count($last8daysLoginPlayer)) ? 0 : round( count($intersect8dayLoginPlay) / count($last8daysLoginPlayer), 4 )*100;//3日留存率

            //30日活跃留存
            $last30daysLoginPlayer = $this->getAllPlayer($days30age, 2);//近30天登录的玩家
            $intersect30daysLoginPlayer = array_intersect($yesterdayLoginPlayer, $last30daysLoginPlayer);//30天玩家与昨天玩家交集
            $data['day30ActRemain'][] = empty(count($last30daysLoginPlayer)) ? 0 :  round( count($intersect30daysLoginPlayer) / count($last30daysLoginPlayer), 4) * 100; //30天留存率

		}
		$ret = json_encode($data);
		if($isAllSid) {
            if($isCache == 1) {
                oo::commonOprRedis('common')->set($cacheKey, $ret);
                oo::commonOprRedis('common')->expireAt($cacheKey, strtotime('23:59:59'));
            }
        }

		return $ret;
	}


    /**
     *	留存首页
     */
    public function tableIndex($param)
    {
        $stime = oo::functions()->uint($param['stime']);
        $etime = oo::functions()->uint($param['etime']);

        $page = oo::functions()->uint($param['page']);//起始页数
        $limit = oo::functions()->uint($param['limit']);//每页数量

        $table = otable::remainStatistics();
        $where = '1 = 1 ';
        if(!empty($stime)){
            $sdate = date('Ymd', $stime);
            $where .= " AND date >= {$sdate} ";
        }
        if(!empty($etime)){
            $edate = date('Ymd', $etime);
            $where .= " AND date <= {$edate} ";
        }

        $totalSql = "SELECT COUNT(*) AS total FROM {$table} WHERE $where  ";
        $total = oo::commonOprDb('common')->getOne($totalSql, MYSQLI_ASSOC);
        $data['total'] = $total['total'];

        $sql = " SELECT * FROM {$table} WHERE {$where} ORDER BY date DESC LIMIT {$page}, {$limit}";
//        oo::logs()->debug3('sql:'.$sql);
        $data['list'] = oo::commonOprDb('common')->getAll($sql, 1);

        return json_encode($data);
    }



    /**
	*	设备留存首页
	*/
	public function device($param)
	{
		$stime = oo::functions()->uint($param['stime']);
		$etime = oo::functions()->uint($param['etime']);
		$isCache = oo::functions()->uint($param['isCache']);
        $cacheKey = okeys::keydata('REMAINDEVICE');

        if($isCache == 1) {
            $keydataInfo = oo::commonOprRedis('common')->get($cacheKey);
            if(!empty($keydataInfo)){
                return $keydataInfo;
            }
        }


		$daysList = $this->getDays($stime, $etime, 2);
		$data['daylist'] = $daysList;
		$day1Remain = $day3Remain = $day7Remain = $day1ActRemain = $day3ActRemain = $day7ActRemain = array();
		foreach ($daysList as $day) {//此处已经减少了一天
			$days1ago = $day;
			$days2ago = date('Ymd', strtotime($day.'-1 day'));
			$days3age = date('Ymd', strtotime($day.'-3 days'));
			$days8age = date('Ymd', strtotime($day.'-7 days'));
			$days30age = date('Ymd', strtotime($day.'-30 days'));//30天没数据，先按29天的算
//			$days30age = date('Ymd', strtotime($day.'-20 days'));

            ////次日新增留存 比如今天29号 就计算28号的次日留存 那么新增玩家从27号算,
			$yesterdayPlayer = $this->getAllDevicePlayer($days1ago, 1);//登陆玩家
			$last2daysPlayer = $this->getAllDevicePlayer($days2ago, 2);//新增玩家

			$intersect1dayPlay = array_intersect($yesterdayPlayer, $last2daysPlayer);//交集玩家
			$tempDay1Remain = empty(count($last2daysPlayer)) ? 0 : count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
			$data['day1Remain'][] = round($tempDay1Remain, 4)*100;//次日留存率
			//$data['day1Remain'][] = count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率

			//3日新增留存
			$last3daysPlayer = $this->getAllDevicePlayer($days3age, 2);//新增玩家
			$intersect3dayPlay = array_intersect($yesterdayPlayer, $last3daysPlayer);//交集玩家
			//$data['day3Remain'][] = count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
			$tday3Remain = empty(count($last3daysPlayer)) ? 0 :  count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
			$data['day3Remain'][] = round($tday3Remain, 4)*100;//3日留存率

			//7日新增留存
			$last8daysPlayer = $this->getAllDevicePlayer($days8age, 2);//新增玩家
			$intersect8dayPlay = array_intersect($yesterdayPlayer, $last8daysPlayer);//交集玩家
			$data['day7Remain'][] = empty(count($last8daysPlayer)) ? 0 : round( count($intersect8dayPlay) / count($last8daysPlayer), 4 )*100;//3日留存率

            //30日新增留存
            $last30daysPlay = $this->getAllDevicePlayer($days30age, 2);//30天新增玩家
            $intersect30dayPlay = array_intersect($yesterdayPlayer, $last30daysPlay); //交集玩家
//            oo::logs()->debug3(array('$last30daysPlay' => $last30daysPlay, '$intersect30dayPlay' => $intersect30dayPlay), 'Keydata.php');
            $data['day30Remain'][] = empty(count($last30daysPlay)) ? 0 : round(count($intersect30dayPlay) / count($last30daysPlay), 4) * 100;//30日留存率

			//次日活跃留存
			$yesterdayLoginPlayer = $this->getAllDevicePlayer($days1ago, 1);//登陆玩家
			$last2daysLoginPlayer = $this->getAllDevicePlayer($days2ago, 1);//登陆玩家
			$intersect1dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last2daysLoginPlayer);//交集玩家
			$data['day1ActRemain'][] = empty(count($last2daysLoginPlayer)) ? 0 : round( count($intersect1dayLoginPlay) / count($last2daysLoginPlayer), 4 )*100;//次日留存率

			//3日活跃留存
			$last3daysLoginPlayer = $this->getAllDevicePlayer($days3age, 1);//登陆玩家
			$intersect3dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last3daysLoginPlayer);//交集玩家
			$data['day3ActRemain'][] = empty(count($last3daysLoginPlayer)) ? 0 : round(count( $intersect3dayLoginPlay) / count($last3daysLoginPlayer), 4 )*100;//3日留存率

			//7日活跃留存
			$last8daysLoginPlayer = $this->getAllDevicePlayer($days8age, 1);//登陆玩家
			$intersect8dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last8daysLoginPlayer);//交集玩家
			$data['day7ActRemain'][] = empty(count($last8daysLoginPlayer)) ? 0 : round( count($intersect8dayLoginPlay) / count($last8daysLoginPlayer), 4 )*100;//3日留存率

            //30日活跃留存
            $last30daysLoginPlayer = $this->getAllDevicePlayer($days30age, 1);//近30天登录的玩家
            $intersect30daysLoginPlayer = array_intersect($yesterdayLoginPlayer, $last30daysLoginPlayer);//30天玩家与昨天玩家交集
            $data['day30ActRemain'][] = empty(count($last30daysLoginPlayer)) ? 0 :  round( count($intersect30daysLoginPlayer) / count($last30daysLoginPlayer), 4) * 100; //30天留存率

		}
		$ret = json_encode($data);
        if($isCache == 1) {
            oo::commonOprRedis('common')->set($cacheKey, $ret);
            oo::commonOprRedis('common')->expireAt($cacheKey, strtotime('23:59:59'));
        }

		return $ret;
	}



	/**
	*	计算所有玩家
	*	type 1 新注册 其他登陆
	*/
	protected function getAllPlayer($date, $type)
	{
	    $sidList = $this->_sidList;
        $total = oo::commonOprModel('statistics')->getAllPlayer($date, $type, $sidList);
        return $total;
	}


    /**
     * 获取该日期的设备号集合
     * @param $date
     * @param $type
     */
	protected function getAllDevicePlayer($date, $type)
    {
        $loginDeviceKey = oo::commonOprModel('statistics')->loginDeviceKey($date, $type);
        $data = oo::commonOprRedis('statistics')->sMembers($loginDeviceKey);
        return $data;
    }


}
