<?php
namespace Admin\Controller;

/**
 * 游戏流水聚合接口
 * @author chenzhi
 */
class SpendCountSetController extends \Think\Controller
{
    public $beginThismonth;
    public $endThismonth;
    public $date;
    public $nowdata;
    public $model;
    public $usermodel;
    public $continue=false;//单元测试,开启后可访问独立函数测试
    public function _initialize(){
        //初始化
        $this->beginThismonth = mktime(0,0,0,date('m')-1,1,date('Y'));
        $this->endThismonth = mktime(0,0,0,date('m'),1,date('Y'))-1;
        $temp = strtotime(date('Y-m-01 00:00:00',strtotime('-1 month')));
        $this->date = date('Y',$temp)."-".date('m',$temp);
        $this->nowdata =time();
        $this->model =M();
        $this->usermodel =M("spend_user_count",'tab_');
        $this->monthmodel =M("spend_month_count",'tab_');
        $this->gamemodel =M("spend_count",'tab_');

    }
    /**
     * 更新某月数据
     */
    public function setMonthSpendCount()
    {
        $month = I("count_date");
        if(empty($month)) die("参数错误");

        $this->date =  $month;
        $tarry = explode('-',$month);
        $this->beginThismonth=mktime(0,0,0,$tarry[1],1,$tarry[0]);
        $this->endThismonth=mktime(0,0,0,$tarry[1]-0+1,1,$tarry[0])-1;
        $this->reCount();
        $this->setSpendCount();
    }
    /**
     * 强制重新聚合
     */
    public function reCount()
    {
        $recount = I("recount");
        if(empty($recount) || $recount != 1){return ;}
        # code...
        //清理之前的聚合
        $temp =array(
            "count_date"=>$this->date
        );
        
        $this->gamemodel->where($temp)->delete();
        $this->usermodel->where($temp)->delete();
        $this->monthmodel->where($temp)->delete();
        echo "重置成功执行重新生成:";
    }


    /**
     * 每个月的统计接口
     */
    public function setSpendCount()
    {
        set_time_limit(0);
        $t1 = microtime(true);
        //判断是否已经聚合
        $countRes = M("spend_count","tab_")->field("count(*) date_count")->where("count_date = '{$this->date}'")->find()['date_count'];
        $countUserRes = M("spend_user_count","tab_")->field("count(*) date_count")->where("count_date = '{$this->date}'")->find()['date_count'];
        if($countRes > 0 || $countUserRes >0){
            die("error:Repeated statistics,msg:{$this->date}已经聚合过");
        }
        $this->model->startTrans();
        $this->continue =true;
        //执行游戏表统计
        $this->setGameCount();
        // //执行用户表统计
        $this->setUserCount();
        // //执行月份统计
        $this->setMonthCount();
        //执行
        $this->model->commit();
        $t2 = microtime(true);
        die("success runtime:".round($t2-$t1,3).'s');
    }
    /**
     * 获取游戏聚合
     */
    public function setGameCount()
    {
        if(!$this->continue){
            die("api error");
        }
        $this->getCashData();
        $this->getBalanceData();
        $this->getInsideData();
        # code...
    }
    //获取游戏现金流水
    protected function getCashData()
    {
        $this->createGameCount("cash_count");
    }
    //获取平台币聚合
    protected function getBalanceData()
    {
        $this->createGameCount("balance_coin_count");
    }
    //获取绑定币充值
    protected function getInsideData()
    {
        $this->createGameCount("inside_cash_count");
        
    }
    protected function createGameCount($type)
    {
        $map = array(
            "pay_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth)),
            "spend.pay_status"=>1
        );
        
        if($type == "cash_count"){
            //现金统计
            $map['pay_way'] = array("GT",0);
        }elseif($type == "balance_coin_count"){
            $map['pay_way']= array("EQ",0);
        }elseif($type == "inside_cash_count"){
            $map['pay_way']= array("LT",0);
        }
        $field = "IFNULL(game.partner_id,0) partner_id,partner.partner partner_name,
                spend.promote_id,spend.promote_account,spend.game_id,spend.game_name,sum(pay_amount) {$type},
                IFNULL(promote.level,0) level,IFNULL(promote.chain,'/') chain,
                '{$this->date}' as count_date,'{$this->nowdata}' as create_time";
        $spendRes = M()
        ->table("tab_spend spend")
        ->field($field)
        ->where($map)
        ->join("tab_promote promote ON spend.promote_id = promote.id","left")
        ->join("tab_game game ON spend.game_id = game.id","left")
        ->join("tab_partner partner ON partner.id = game.partner_id","left")
        ->group('spend.promote_id,spend.game_id')
        ->select();
        if(empty($spendRes)){
            return ;
        }
        //集中两个表
        if($type == "cash_count"){
            $dbres = $this->gamemodel->addAll($spendRes);
            if(!$dbres){
                $this->model->rollback();
                die("error");
            }
        }else{
            for ($i=0; $i < count($spendRes); $i++) { 
                $spendRes[$i][$type] || $spendRes[$i][$type]=0;
                # code...
                $tempmap = array(
                    "game_id"=>$spendRes[$i]['game_id'],
                    "promote_id"=>$spendRes[$i]['promote_id'],
                    "count_date"=>$this->date
                );
                $dbres = $this->gamemodel->where($tempmap)->find();
                if(empty($dbres)){
                    //不存在
                    $tempdbres = $this->gamemodel->add($spendRes[$i]);
                    if(!$tempdbres){
                        $this->model->rollback();
                        die("error");
                    }
                }else{
                    $dbres[$type] = $dbres[$type]-0+$spendRes[$i][$type];
                    $tempdbres = $this->gamemodel->save($dbres);
                    if($tempdbres === false){
                        $this->model->rollback();
                        die("error");
                    }
                }
            }
        }
        # code...
    }

    /** --------以下为设定角色聚合---------- **/
    
    /**
     * 获取角色聚合
     */
    public function setUserCount()
    {
        //获取会长信息
        $adddata=array();
        $userarr = array();
        $this->getUserCountInit($adddata,$userarr);
        $this->getUserInsideData($adddata,$userarr);
        $this->addUserDb($adddata);
    }
    //用户聚合
    public function getUserCountInit(&$adddata,&$userarr)
    {

        $gameres = $this->gamemodel->field("sum(cash_count) cash_count,sum(balance_coin_count) balance_coin_count,sum(inside_cash_count) bind_coin_count,chain,level,promote_id,promote_account")
             ->where("count_date='{$this->date}'")->group("promote_id")->select();
        if(empty($gameres)){
            return;
        }
        $count = count($gameres);
        $adddata=array();
        $userarr = array();
        //执行
        for ($i=0; $i < $count; $i++) {
            $d =  $gameres[$i];
            if($d['level'] < 2){
                $adddata[$d['promote_id']] = $d;
                $userarr[] =$d['promote_id'];
            }else{
                //获取所有链路
                $chain = trim($d['chain'],"/");
                $pid = explode("/", $chain);
                $pid[] = $d['promote_id'];//添加自己
                for ($k=0; $k <count($pid); $k++) { 
                    if(in_array($pid[$k], $userarr)){
                        //存在
                        $adddata[$pid[$k]]["cash_count"] += $d['cash_count'];
                        $adddata[$pid[$k]]["balance_coin_count"] += $d['balance_coin_count'];
                        $adddata[$pid[$k]]["bind_coin_count"] += $d['bind_coin_count'];
                    }else{
                        //不存在
                        //获取链路
                        $temp =  $this->getChain($pid[$k]);
                        $temp['cash_count'] = $d['cash_count'];
                        $temp['balance_coin_count'] = $d['balance_coin_count'];
                        $temp['bind_coin_count'] = $d['bind_coin_count'];

                        $adddata[$pid[$k]] = $temp;
                        $userarr[] =$pid[$k];
                    }
                }
            }
        }
    }
    //获取chain
    protected function getChain($id){
        return M("Promote","tab_")->field("id promote_id,account promote_account,chain,level")->where("id='".$id."'")->find();
    }
    //渠道角色统计仅计算推广员的平台币发放与收回
    protected function getUserInsideData(&$adddata,&$userarr)
    {
        $insideRes = M()
            ->table("tab_promote_coin")
            ->field("*")
            ->where(array(
                "create_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth)),
                "source_id"=>0,
                "status"=>1
            ))
            ->select();
        if(!empty($insideRes)){
            for ($i=0; $i < count($insideRes); $i++) { 
                # code...
                if($insideRes[$i]['type'] > 1){
                    $insideRes[$i]['num'] = ( 0- $insideRes[$i]['num']);
                }
                //获取链路
                $d =  $this->getChain($insideRes[$i]['promote_id']);
                
                $chain = trim($d['chain'],"/");
                $pid = explode("/", $chain);
                $pid[] = $d['promote_id'];//添加自己
                if($d['level'] < 2){
                    if(in_array($d["promote_id"], $userarr)){
                        //存在
                        $adddata[$pid[$k]]["inside_cash_count"] += $insideRes[$i]['num'];
                    }else{
                        $d['inside_cash_count'] = $insideRes[$i]['num'];
                        $adddata[$d['promote_id']] = $d;
                        $userarr[] =$d['promote_id'];
                    }
                }else{
                    for ($k=0; $k <count($pid); $k++) { 
                        if(in_array($pid[$k], $userarr)){
                            //存在
                            $adddata[$pid[$k]]["inside_cash_count"] += $insideRes[$i]['num'];
                        }else{
                            //不存在
                            //获取链路
                            $temp =  $this->getChain($pid[$k]);
                            $temp['inside_cash_count'] = $insideRes[$i]['num'];
    
                            $adddata[$pid[$k]] = $temp;
                            $userarr[] =$pid[$k];
                        }
                    }
                }
            }
        }

    }
    //添加用户统计表
    protected function addUserDb(&$adddata){
        $count = count($adddata);
        if($count < 1){return;}
        foreach ($adddata as $k => $v) {
            isset($v["cash_count"]) || $v["cash_count"]=0;
            isset($v["balance_coin_count"]) || $v["balance_coin_count"]=0;
            isset($v["bind_coin_count"]) || $v["bind_coin_count"]=0;
            isset($v["inside_cash_count"]) || $v["inside_cash_count"]=0;
            //设定时间
            $v["count_date"] = $this->date;
            $v["create_time"] = $this->nowdata;
            //聚合不含内充流水
            $v['all_count'] = $v["cash_count"]-0+$v["balance_coin_count"]-0+$v["bind_coin_count"];
            $tempdbres = $this->usermodel->add($v);
            if($tempdbres === false){
                $this->model->rollback();
                die("addUserDb error");
            }
        }
    }
    
    /** --------以下为设定月份聚合---------- **/
    /**
     * @param 现金流水 cash_count 游戏中充值的现金
     * @param 平台币流水 balance_coin_count 游戏中消耗的平台币
     * @param 绑定币流水 bind_coin_count 游戏中绑定币的消耗
     * @param 内充流水 inside_cash_count:(推广员的平台币发放-收回)+(后台发放给玩家平台币-回收平台币 )+ (后台发放绑币给玩家 -回收的绑币)
     * @param 平台币充值 balance_coin_deposit
     * @return void
     */
    public function setMonthCount()
    {
        $initdata = $this->getMonthInit();
        $balance  = $this->getBalanceUser();
        $bind  = $this->getBindUser();
        $deposit = $this->getBalanceDeposit();
        $initdata["inside_cash_count"] = $initdata["inside_cash_count"]-0+$balance-0+$bind;
        $initdata["balance_coin_deposit"] = $deposit;
        $initdata["all_count"] = $initdata["inside_cash_count"]-0+$initdata["cash_count"]-0+$deposit;
        $initdata["count_date"] = $this->date;
        $initdata["create_time"] = $this->nowdata;
        $tempdbres = $this->monthmodel->add($initdata);
        if($tempdbres === false){
            $this->model->rollback();
            die("setMonthCount error");
        }
        # code...
    }
    //获取除了内充的
    protected function getMonthInit()
    {
        $tempmap = array(
            "count_date"=>$this->date,
            "level"=>array("LT",2)
        );
        return  $this->usermodel->field("sum(cash_count) cash_count,sum(balance_coin_count) balance_coin_count,sum(bind_coin_count) bind_coin_count,sum(inside_cash_count) inside_cash_count")->where($tempmap)->find();
    }
    //获取平台币充值流水
    protected function getBalanceDeposit()
    {
        $map = array(
            "create_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth)),
            "pay_status"=>1
        );
        $deposit = M("deposit","tab_")->field("SUM(pay_amount) pay_amount")->where($map)->find()['pay_amount'];
        $deposit || $deposit=0;
        return $deposit;
    }
    //设置 后台发放平台币给玩家 及 回收玩家 的最终值
    protected function getBalanceUser()
    {
        $map = array(
            "create_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth)),
            "status"=>1
        );
        $add = M("provide_user","tab_")->field("sum(amount) amount")->where($map)->find()['amount'];
        $add || $add=0;

        $jq = M("user_coin","tab_")->field("sum(num) num")->where(array(
            "create_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth))
        ))->find()['num'];
        $jq || $jq=0;
        return  $add-$jq;
    }
    //设置 后台发放绑币给玩家 及 回收玩家绑币 的最终值
    protected function getBindUser()
    {
        $map = array(
            "create_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth)),
            "status"=>1
        );
        $add = M("provide","tab_")->field("sum(amount) amount")->where($map)->find()['amount'];
        $add || $add=0;
        

        $jq = M("deduct_bind_record","tab_")->field("sum(quantity) quantity")->where(array(
            "create_time"=> array('BETWEEN',array($this->beginThismonth, $this->endThismonth))
        ))->find()['quantity'];
        $jq || $jq=0;
        return  $add-$jq;
    }
    
}