<?php
/**
 * Created by PhpStorm.
 * User: leo
 * Date: 2018/2/24
 * Time: 下午12:48
 */

namespace backendApi\modules\v1\controllers;

use common\helpers\bonus\Calc\CalcConsole;
use common\helpers\bonus\Calc\PullCalcBonusData;
use common\helpers\Form;
use common\models\CalcRecord;
use common\models\FlowBonus;
use common\models\forms\PeriodForm;
use common\models\Period;
use common\models\CalcOperation;
use Yii;

/**
 * 业务系统关于计算服务的控制器
 */

class CalcController extends BaseController
{
    public $modelClass = FlowBonus::class;

    public function behaviors()
    {
        $behaviors = parent::behaviors();
        return $behaviors;
    }

//    public function actionAutoPerf() {
//        $periodNum = \Yii::$app->request->get('periodNum');
//        if (!$periodNum) {
//            return static::notice('期数不存在', 400);
//        }
//        if (Period::isPreparing($periodNum)) {
//            return static::notice('预计算正在进行中请稍后', 400);
//        }
//        //设置自动计算标识
//        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);
//        //记录开始计算的时间
//        $calc_id = uniqid('perf_');
//        CalcOperation::record($calc_id, $periodNum);
//        Period::updateAll(['START_EXEC_TIME' => time(), 'CALC_ID' => $calc_id], ['PERIOD_NUM' => $periodNum]);
//
//        $formModel = new PeriodForm();
//        $formModel->scenario = 'autoPerf';
//
//        if ($formModel->load(Yii::$app->request->get(), '') && $formModel->autoPerf()) {
//            //设置预计算进行中标识
//            Period::updatePeriodIsPreparing($periodNum, Period::IS_PREPARING);
//            //设置redis开关
//            Yii::$app->cache->set('isPreparing', 1, 3600);
//            return static::notice('预计算已开始，请等待');
//        } else {
//            return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
//        }
//    }

    /**自动计算 对应界面按钮
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionAutoCalc()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
//        if (!Period::checkClose($periodNum)) { // 如果未封期
//            return static::notice('没有封期不能计算', 400);
//        }
        //设置计算进行中标识
        Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);
        //设置自动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::AUTO_EXEC_CALC);
        //记录开始计算的时间
        $calc_id = uniqid('calc_');
        CalcOperation::record($calc_id, $periodNum);
        Period::updateAll(['START_EXEC_TIME' => time(), 'CALC_ID' => $calc_id], ['PERIOD_NUM' => $periodNum]);

        $formModel           = new PeriodForm();
        $formModel->scenario = 'perf';

        if ($formModel->load(Yii::$app->request->get(), '') && $formModel->autoExec()) {
            //设置redis开关
            Yii::$app->cache->set('isCalcing', 1, 3600);
            return static::notice('自动计算已开始，请等待');
        } else {
            return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
        }
    }

    /**
     * 生成业绩单
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionPerfOrder()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
        //设置手动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);
        //设置计算进行中标识
        Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);
        //记录开始计算的时间
        $calc_id = uniqid('manu_');
        CalcOperation::record($calc_id, $periodNum);
        Period::updateAll(['START_EXEC_TIME' => time(), 'CALC_ID' => $calc_id], ['PERIOD_NUM' => $periodNum]);

        $formModel           = new PeriodForm();
        $formModel->scenario = 'perf';

        if ($formModel->load(Yii::$app->request->get(), '') && $formModel->generatePerfOrder()) {
            //设置redis开关
            Yii::$app->cache->set('isCalcing', 1, 3600);
            return static::notice('业绩单已开始生成，请等待');
        } else {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
        }
    }


    /**
     * 推送基础数据
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionInitData()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
        //设置手动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);
        //设置计算进行中标识
        Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);

        $formModel           = new PeriodForm();
        $formModel->scenario = 'perf';

        if ($formModel->load(Yii::$app->request->get(), '') && $formModel->pushBaseData()) {
            return static::notice('基础数据已开始推送，请等待');
        } else {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
        }
    }


    /**
     * 通知计算系统生成期业绩和月业绩单
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionCalcPerfPeriod()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
        //设置手动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);
        //设置计算进行中标识
//        Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);

        $db     = CalcConsole::CALC_DB_NAME;
        $period = \Yii::$app->$db->createCommand('SELECT * FROM AR_PERIOD where PERIOD_NUM=:PERIOD_NUM')
            ->bindValue(':PERIOD_NUM', $periodNum)
            ->queryOne();
        $businessPeriod = Period::find()->where(['PERIOD_NUM' => $periodNum])->asArray()->one();
        if (!$period['CALC_ID'] || $period['CALC_ID'] != $businessPeriod['CALC_ID']) {
            return static::notice('CALC ID不符', 400);
        }

        if (empty($period)) {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice('计算系统中的第' . $periodNum . '期的业绩期信息不存在');
        } else {
            CalcRecord::record($periodNum, '【期业绩】已通知计算系统生成本期的期业绩');
            \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 1], 'PERIOD_NUM=' . $periodNum)->execute();
            return static::notice('期业绩已于计算系统中开始计算，请等待');
        }
    }

    /**
     * 拉取期业绩和月业绩到业务系统
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionPullPerfPeriod()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
        //设置手动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);

        $db     = CalcConsole::CALC_DB_NAME;
        $period = \Yii::$app->$db->createCommand('SELECT * FROM AR_PERIOD where PERIOD_NUM=:PERIOD_NUM')
            ->bindValue(':PERIOD_NUM', $periodNum)
            ->queryOne();
        $businessPeriod = Period::find()->where(['PERIOD_NUM' => $periodNum])->asArray()->one();
        if (!$period['CALC_ID'] || $period['CALC_ID'] != $businessPeriod['CALC_ID']) {
            return static::notice('CALC ID不符', 400);
        }

        if (empty($period)) {
            return static::notice('计算系统中的第' . $periodNum . '期的业绩期信息不存在');
        }
        $formModel           = new PeriodForm();
        $formModel->scenario = 'perf';

        //设置计算进行中标识
        Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);
        if ($formModel->load(Yii::$app->request->get(), '') && $formModel->pullPeriod()) {
            return static::notice('开始拉取期业绩数据，请等待');
        } else {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
        }
    }

    /**
     * 通知业务系统计算奖金
     * @return mixed|void
     * @throws \yii\web\HttpException
     */
    public function actionCalcBonus()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
        //设置手动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);
        //设置计算进行中标识
//        Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);
        $db     = CalcConsole::CALC_DB_NAME;
        $period = \Yii::$app->$db->createCommand('SELECT * FROM AR_PERIOD where PERIOD_NUM=:PERIOD_NUM')
            ->bindValue(':PERIOD_NUM', $periodNum)
            ->queryOne();
        $businessPeriod = Period::find()->where(['PERIOD_NUM' => $periodNum])->asArray()->one();
        if (!$period['CALC_ID'] || $period['CALC_ID'] != $businessPeriod['CALC_ID']) {
            return static::notice('CALC ID不符', 400);
        }

        $formModel           = new PeriodForm();
        $formModel->scenario = 'calc';
        if (empty($period)) {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice('计算系统中的第' . $periodNum . '期的业绩期信息不存在');
        } else/* if (1 == $period['IS_PERFED'] && 2 == $period['IS_PREPARE']) */ {
            Period::updateAll(['IS_CALCULATED' => 0, 'IS_CALCING' => 1], ['PERIOD_NUM' => $period['PERIOD_NUM']]);
            //设置奖金开始计算时间
            Period::updateAll(['START_EXEC_TIME' => time()], ['PERIOD_NUM' => $periodNum]);
            CalcRecord::record($periodNum, '【奖金计算】开始计算第'.$periodNum.'期的奖金');
            \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 3, 'IS_CALCULATED' => 0], 'PERIOD_NUM=' . $periodNum)->execute();
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice('本期奖金已于计算系统中开始计算，请等待');
        }
    }

    /**拉取奖金
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionPullBonus()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        if (Period::isProcessing($periodNum)) {
            return static::notice('有操作正在进行中请稍后', 400);
        }
        //设置手动计算标识
        Period::updatePeriodIsAutoExec($periodNum, Period::MANUAL_EXEC_CALC);

        $db     = CalcConsole::CALC_DB_NAME;
        $period = \Yii::$app->$db->createCommand('SELECT * FROM AR_PERIOD where PERIOD_NUM=:PERIOD_NUM')
            ->bindValue(':PERIOD_NUM', $periodNum)
            ->queryOne();
        $businessPeriod = Period::find()->where(['PERIOD_NUM' => $periodNum])->asArray()->one();
        if (!$period['CALC_ID'] || $period['CALC_ID'] != $businessPeriod['CALC_ID']) {
            return static::notice('CALC ID不符', 400);
        }

        if (empty($period)) {
            return static::notice('计算系统中的第' . $periodNum . '期的业绩期信息不存在');
        }

        $formModel           = new PeriodForm();
        $formModel->scenario = 'calc';

        if (4 == $period['IS_PREPARE'] && 1 == $period['IS_CALCULATED']) {
            //设置计算进行中标识
            Period::updatePeriodIsProcessing($periodNum, Period::IS_PROCESSING);
            if ($formModel->load(Yii::$app->request->get(), '') && $formModel->pullBonus()) {
                return static::notice('开始拉取奖金数据，请等待');
            } else {
                Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
            }
        } else {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            return static::notice('奖金数据还未全部生成，无法全部拉取，请稍后重试', 400);
        }

    }

    /**操作记录列表
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionRecordList()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        $data = CalcRecord::find()->where('CALC_ID=:PERIOD_NUM', [':PERIOD_NUM' => $periodNum])->orderBy('CREATE_TIME ASC')->asArray()->all();
        return static::notice(['list' => $data]);
    }

    /**
     * 更新奖金计算进度的日志
     * @return mixed
     * @throws \yii\web\HttpException
     */
    public function actionSyncCalcRecord()
    {
        $periodNum = \Yii::$app->request->get('periodNum');
        if (!$periodNum) {
            return static::notice('期数不存在', 400);
        }
        $businessPeriod = Period::find()->where(['PERIOD_NUM' => $periodNum])->asArray()->one();
        CalcConsole::syncCalcRecord($periodNum, CalcConsole::CALC_DB_NAME, $businessPeriod['START_EXEC_TIME'] ?? 0);
        return static::notice('已更新奖金计算的操作日志，请刷新');
    }


}
