<?php

namespace addons\csmtable\controller;

use addons\csmtable\library\xcore\xcore\utils\XcConfigUtils;
use addons\csmtable\library\xcore\xcore\utils\XcDaoUtils;
use addons\csmtable\library\xcore\xcore\utils\XcRequestUtils;
use addons\csmtable\library\xcore\xcore\base\XcAAdminApi;
use addons\csmtable\library\xapp\csmtable\utils\CsmTableUtils;
use addons\csmtable\library\xapp\csmtable\utils\CsmgenerateTask;

class Csmgenerate extends XcAAdminApi
{
    protected $noNeedRight = ["*"];
    protected $xlstaskdao = null;

    // config 配置
    protected $excelmaxrecoredcount = null;
    protected $controlpagesize = null;

    protected $uploadtmppath = RUNTIME_PATH . 'temp' . DS;

    protected function xinit()
    {
        $this->xlstaskdao = new \app\admin\model\csmtable\Xlstask();

        $this->excelmaxrecoredcount = (int)XcConfigUtils::config("excelmaxrecoredcount");
        $this->controlpagesize = XcConfigUtils::config("controlpagesize");
    }

    public function index()
    {
        
        $id = XcRequestUtils::get("id", true);
        $ret = $this->_index($id);
        if ($ret === true) {
            echo "操作成功！";
        } else {
            echo $ret;
        }
    }

    private function _index($id)
    {
        static::p('----generateExcelByClassname begin:');
        set_time_limit(0);

        $params = $this->getXlstaskParams($id);
        $this->setProgress($id, 10);
        // 按记录数切分多个任务
        $recordtotal = $this->getDataRecordTotal($params);

        $excelCount = (int) ($recordtotal / $this->excelmaxrecoredcount); // 总记录数/单个xls记录数=200/100=2

        if ($recordtotal == 0) {
            // 没有数据,则报错
            $errmsg = "没有数据，无法下载";
            $this->setErrorXlstask($id, $errmsg);
            static::p('----generateExcelByClassname end:');
            return $errmsg;
        }

        $result = '';
        $excelFiles = [];
        for ($i = 0; $i <= $excelCount; $i++) {
            static::p($i);
            $fileno =  ($i + 1);
            $offset = $i * $this->excelmaxrecoredcount;

            $task = new CsmgenerateTask();
            $filename = $task->index($id, $fileno, $offset);
            $result =  $filename . ';';

            $progress = (int) 80 * ($i + 1) / ($excelCount + 2) + 10;
            $this->setProgress($id, $progress);


            if ($filename != null) {
                $excelFiles[] = $filename;
                static::p($filename);
            } else {
                $errmsg = '下载报错,可能是PHP内存设置过小或数据查询报错造成';
                $this->setErrorXlstask($id, $errmsg);
                return $errmsg;
            }
        }

        $this->setProgress($id, 90);

        $zipfilename = static::saveExcelToZip($excelFiles);
        $this->setProgress($id, 100, $zipfilename, $result);
        static::p('----generateExcelByClassname end:' . $result);
        return true;
    }





    public function saveExcelToZip(&$excelFiles)
    {
        $zipfn = 'csmtable_' . time() . '.zip';
        $zipfilename = $this->uploadtmppath . $zipfn;
        $zip = new \ZipArchive();
        $zip->open($zipfilename, \ZipArchive::CREATE | \ZipArchive::CREATE);
        static::p('saveExcelToZip');
        static::p($excelFiles);
        foreach ($excelFiles as $item) {
            $zip->addFile($this->uploadtmppath . $item, $item);
        }
        $zip->close();

        foreach ($excelFiles as $item) {
            unlink($this->uploadtmppath . $item);
        }
        return $zipfn;
    }



    private function setProgress(&$csmtable_xlstask_id, $progress, $filename = '', $errormsg = '')
    {
        $this->xlstaskdao->where("id", "=", $csmtable_xlstask_id)->update([
            'progress' => $progress,
            'filename' => $filename,
            'updatetime' => time(),
            'errormsg' => $errormsg //v2.1.8 增加日志和查询日志调试功能,便于排查问题
        ]);
        static::p('progress:' . $progress);
    }

    private function setErrorXlstask($csmtable_xlstask_id, $errormsg)
    {
        XcDaoUtils::getRowById($this->xlstaskdao, $csmtable_xlstask_id)->save([
            'iserror' => 'Y',
            'errormsg' => substr($errormsg, 0, 1000),
            'updatetime' => time()
        ]);
        static::p('progress:' . $errormsg);
    }


    // 获取记录数
    public function getDataRecordTotal(&$params)
    {
        $controlData = CsmTableUtils::callRemoteControl($params, 0, 1);
        return $controlData->getData()['total'];
    }

    public function getXlstaskParams($id)
    {

        $xlstaskrow = XcDaoUtils::getRowById($this->xlstaskdao, $id);
        if ($xlstaskrow == null) {
            return;
        }
        return json_decode($xlstaskrow->param, true);
    }


    private static function p($str)
    {
        trace($str);
        //echo($str."<BR>");
    }
}
