<?php
namespace model\bi;
/** 取数据
 * Class getData
 * @package model
 */
class getData extends \model
{
    public $dbbi;
    public $cache;
    public $cacheTime=3600; //缓存时间
    public $dircfg;
    public $cols;
    public $cfgs;
    public $captions;
	public function __construct()
    {
		$db = new \lib\db(\mvc::$cfg['db']['main']);
		parent::__construct();
		$cacheDir = \mvc::$cfg['dir']['cache'].'/bi';
		mkdirs($cacheDir);
		$cache = new \lib\cache($cacheDir);
		$this->dbbi = new \lib\db(\mvc::$cfg['db']['main']);
		$this->cache = $cache;
		$this->dircfg = \mvc::$cfg['dir']['project'].'/config/bi';
		$cols = require($this->dircfg.'/cols.php');
		$this->cols = $cols;
		$this->captions = [];
	}
	
	function getConfig($code){
	    $style = require($this->dircfg.'/style.php');
	    if(!isset($this->cfgs[$code])){
    	    $this->cfgs[$code] = require($this->dircfg.'/chart/'.$code.'.php');
	    }
	    return $this->cfgs[$code];
	}
	

	function getCaption($code,$field,$value){
	    $key = $code.'-'.$field.'-'.$value;
	    if(!isset($this->captions[$key])){
    	    $cfg = $this->getConfig($code);
    	    $table = $cfg['table'].'_dimension';
    	    $this->captions[$key] = $this->dbbi->get($table,cateName(),['dimension'=>$field,'key'=>$value]);
	    }
	    return $this->captions[$key];
	}
	
	public function getDimension($code,$field,$rules=[])
    {
	    $cfg = $this->getConfig($code);
	    $table = $cfg['table'];
	    $rules['GROUP'] = $field;
        $rows = $this->dbbi->select($table,$field,$rules);
        $data = [];
        foreach($rows as $value){
            $data[] = ['key'=>$value,'value'=>$this->getCaption($code,$field,$value)];
        }
        return $data;
    }
    
	public function getDimensionAllKey($code,$field)
    {
	    $cfg = $this->getConfig($code);
	    $table = $cfg['table'].'_dimension';
        $data = $this->dbbi->select($table,'key',['dimension'=>$field]);
        return $data;
    }

	public function put($code,$rules=[],$series='',$axis='',$countType='')
    {
	    $cfg = $this->getConfig($code);
        $cfg['cols'] = $this->cols;
        foreach($rules as $k=>$v){
            preg_match('/(.*)\{(.*)\}/',$k,$m);
            if(isset($m[2]) && $m[2]){
                $newKey = $m[1].'['.$m[2].']';
                $rules[$newKey] = $v;
            }
            if(!in_array($k,$cfg['options']['search'])){
                unset($rules[$k]);
            }
        }
        if($series!=''){
            $cfg['series'] = $series;
        }
        if($axis!=''){
            $cfg['fields']['axis'] = $axis;
        }

        $type = $cfg['echarts']['series'][0]['type'];
        $cfg['chartType'] = $type;
        if($type=='pie'){
            $data = $this->getChartCountData($code,$cfg,$countType,$rules);
            $cfg['echarts']['series'][0]['data'] = $data['serie'];
            $cfg['echarts']['title']['subtext'] = $data['count'];
        }else if($type=='map'){
            $data = $this->getChartMapData($code,$cfg,$rules);
            $cfg['echarts']['series'][0]['data'] = $data['serie'];
            $cfg['echarts']['extData']['min'] = $data['min'];
            $cfg['echarts']['extData']['max'] = $data['max'];
        }else{ //bar
            $axisData = [];
            $serieData = [];
            if(isset($cfg['series']) && isset($rules[$cfg['series']])){
                $series = $rules[$cfg['series']];
                if($series=='all') $series = $this->getDimensionAllKey($code,$cfg['series']);
                if(!is_array($series)) $series = [$series];
                unset($rules[$cfg['series']]);
                foreach($series as $k=>$serie){
                    $name = $this->getCaption($code,$cfg['series'],$serie);
                    if(empty($name)) continue;
                    $where = $rules;
                    $where[$cfg['series']] = $serie;
                    $data = $this->getChartData($code,$cfg,$where);
                    foreach($data['axis'] as $v){
                        if(!in_array($v,$axisData)) $axisData[] = $v;
                    }
                    $cfg['echarts']['series'][$k] = [
                        'name'=>$name,
                        'type'=>$type,
                        'data'=>$data['serie']
                    ];
                    $cfg['echarts']['legend']['data'][] = $name;
                }
            }else{
                $data = $this->getChartData($code,$cfg,$rules);
                $axisData = $data['axis'];
                $serieData = $data['serie'];
                $cfg['echarts']['series'][0]['data'] = $serieData;
            }
            if($cfg['echarts']['xAxis']['type']=='category'){
                $cfg['echarts']['xAxis']['data'] = $axisData;
            }
            if($cfg['echarts']['yAxis']['type']=='category'){
                $cfg['echarts']['yAxis']['data'] = $axisData;
            }
        }
        return $cfg;
	}
	
	public function getChartData($code,$cfg,$rules)
    {
        $sqlKeys = [
            'axis'=> $cfg['fields']['axis'],
            'series'=> $cfg['series'],
            'where'=> $this->dbbi->whereToSql($rules),
        ];
        $querySql = qgprintf($cfg['sql'],$sqlKeys);
        //dd($cfg,$cfg['sql'],$querySql);
        $st = $this->dbbi->query($querySql);
        $rows = $st->fetchAll();
        
        $axisField = $cfg['fields']['axis'];
        $valueField = $cfg['fields']['value'];
        $axisData = [];
        $serieData = [];
        foreach($rows as $row){
            array_push($axisData,$this->getCaption($code,$axisField,$row[$axisField]));
            array_push($serieData,$row[$valueField]);
        }
        return ['axis'=>$axisData,'serie'=>$serieData];
    }

	public function getChartCountData($code,$cfg,$countType,$rules)
    {
        $sqlKeys = [
            'axis'=> '',
            'series'=> $cfg['series'],
            'where'=> $this->dbbi->whereToSql($rules),
        ];
        $querySql = qgprintf($cfg['sql'],$sqlKeys);
        if($countType=='all' || $countType==''){
            if(isset($cfg['maxCountSql']) && $cfg['maxCountSql']){
                $countSql = $cfg['maxCountSql'];
            }else{
                foreach($sqlKeys as $k=>$v) $sqlKeysNull[$k]='';
                $countSql = qgprintf($cfg['countSql'],$sqlKeysNull);
            }
        }else if($countType=='rule'){
            $countSql = qgprintf($cfg['countSql'],$sqlKeys);
        }
        $count = $this->dbbi->query($countSql)->fetchColumn(0);
        $st = $this->dbbi->query($querySql);
        $rows = $st->fetchAll();
        $valueField = $cfg['fields']['value'];
        $serieData = [];
        $total = 0;
        foreach($rows as $row){
            array_push($serieData,[
                'value'=>$row[$valueField],
                'name'=> $this->getCaption($code,$cfg['series'],$row[$cfg['series']])
            ]);
            $total += $row[$valueField]*1;
        }
        if($count!=$total){
            array_push($serieData,[
                'value'=> ($count - $total),
                'name'=> lg('其余')
            ]);
        }
        return ['count'=>$count,'serie'=>$serieData];
    }

	public function getChartMapData($code,$cfg,$rules)
    {
        $sqlKeys = [
            'axis'=> '',
            'series'=> $cfg['series'],
            'where'=> $this->dbbi->whereToSql($rules),
        ];
        $querySql = qgprintf($cfg['sql'],$sqlKeys);
        $st = $this->dbbi->query($querySql);
        $rows = $st->fetchAll();
        $valueField = $cfg['fields']['value'];
        $serieData = [];
        $min = -1;
        $max = 100;
        foreach($rows as $row){
            $name = $this->getCaption($code,$cfg['series'],$row[$cfg['series']]);//'ID_'.$row[$cfg['series']];
            $value = $row[$valueField];
            array_push($serieData,[
                'value'=>$row[$valueField],
                'name'=> $name
            ]);
            if($value < $min || $min == -1 ) $min = $value;
            if($value > $max ) $max = $value;
        }
        return ['min'=>$min,'max'=>$max,'serie'=>$serieData];
    }
}