<?php
/**
 * Created by PhpStorm.
 * User: leo
 * Date: 2018/3/9
 * Time: 上午11:56
 */

namespace console\controllers;

use common\helpers\bonus\Calc\CalcConsole;
use common\helpers\bonus\Calc\GeneratePerfOrder;
use common\helpers\bonus\Calc\PullCalcBonusData;
use common\helpers\bonus\Calc\PullPerfDataFromCalc;
use common\helpers\bonus\Calc\PushBaseDataToCalc;
use common\helpers\Cache;
use common\models\CalcRecord;
use common\models\Period;
use common\models\CalcOperation;


class CalcController extends BaseController
{
    const  CALC_DB_NAME = 'dbCalcServer';
    public function actionPerfOrder($taskKey)
    {
        $params    = Cache::getAsyncParams($taskKey);
        $periodNum = $params['periodNum'] ?? 0;
        CalcRecord::record($periodNum, '【生成业绩单】业务系统，业绩单生成中');
        //生成业绩单 状态已修改
        $res = (new GeneratePerfOrder($periodNum))->start();
        //该期状态改为不在计算中
//        Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);

        if (200 == $res['code']) {
            self::recordCalcAndProcessStatus($periodNum, '【生成业绩单】业务系统，业绩单已生成');
            \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "第{$params['periodNum']}期生成业绩单更新成功");
            return true;
        } else {
            self::recordCalcAndProcessStatus($periodNum, '【生成业绩单】业务系统，业绩单生成失败,原因：' . substr($res['msg'],0,1000) ?? '');
            \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "第{$params['periodNum']}期生成业绩单更新失败,原因：" . $res['msg'] ?? '', false);
            return false;
        }
    }

    //自动执行
    public static function actionAutoExec($taskKey): bool
    {
        $params    = Cache::getAsyncParams($taskKey);
        $periodNum = $params['periodNum'] ?? 0;
        //生成业绩单 状态已修改
        CalcRecord::record($periodNum, '【生成业绩单】业务系统，开始生成业绩单');
        //重置业务系统的计算进度标识
        \Yii::$app->db->createCommand()->update('AR_PERIOD', ['IS_PERFED' => 0, 'IS_CALCULATED' => 0], 'PERIOD_NUM=' . $periodNum)->execute();
        //重置计算系统的计算进度标识
        $db = CalcConsole::CALC_DB_NAME;
        \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 0, 'IS_PERFED' => 0, 'IS_CALCULATED' => 0], 'PERIOD_NUM=' . $periodNum)->execute();

        $res = (new GeneratePerfOrder($periodNum))->start();
        if (200 == $res['code']) {
            CalcRecord::record($periodNum, '【生成业绩单】业务系统，业绩单已生成');
        } else {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            CalcRecord::record($periodNum, '【生成业绩单】业务系统，第' . $periodNum . '期业绩单生成失败，原因：' . substr($res['msg'],0,100));
            return false;
        }

        //推送基础数据
        CalcRecord::record($periodNum, '【基础数据】开始推送基础数据');
        $res = (new PushBaseDataToCalc($periodNum))->start();
        if (200 == $res['code']) {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            CalcRecord::record($periodNum, '【基础数据】基础数据完成推送');
        } else {
            Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
            CalcRecord::record($periodNum, '【基础数据】第' . $periodNum . '期基础数据推送失败，原因：' . $res['msg']);
            return false;
        }
        //todo 完成需要修改状态

        //通知结算系统生成期业绩
        CalcRecord::record($periodNum, '【基础数据】开始生成' . $periodNum . '期的期业绩');
        \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 1], 'PERIOD_NUM=' . $periodNum)->execute();
        //todo 完成需要修改状态

        //自动监听 拉取期业绩 并计算奖金
//        (new PullPerfDataFromCalc($periodNum))->start();
        //通知结算系统计算奖金
//        \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 3], 'PERIOD_NUM=' . $periodNum)->execute();

        //自动监听 计算完成 自动拉取奖金结果并修改状态
//        (new PullCalcBonusData($period['PERIOD_NUM']))->start();
        return true;
    }

    //自动计算业绩
    public static function actionAutoPerf($taskKey): bool
    {
        $params    = Cache::getAsyncParams($taskKey);
        $periodNum = $params['periodNum'] ?? 0;
        //生成业绩单 状态已修改
        CalcRecord::record($periodNum, '【生成业绩单】开始生成业绩单');
        //重置业务系统的计算进度标识
        \Yii::$app->db->createCommand()->update('AR_PERIOD', ['IS_PERFED' => 0, 'IS_CALCULATED' => 0], 'PERIOD_NUM=' . $periodNum)->execute();
        //重置计算系统的计算进度标识
        $db = CalcConsole::CALC_DB_NAME;
        \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 0, 'IS_PERFED' => 0, 'IS_CALCULATED' => 0], 'PERIOD_NUM=' . $periodNum)->execute();

        $res = (new GeneratePerfOrder($periodNum))->start();
        if (200 == $res['code']) {
            CalcRecord::record($periodNum, '【生成业绩单】业绩单已生成');
        } else {
            Period::updatePeriodIsPreparing($periodNum, Period::NOT_PREPARING);
            CalcRecord::record($periodNum, '【生成业绩单】第' . $periodNum . '期业绩单生成失败，原因：' . substr($res['msg'],0,100));
            return false;
        }

        //推送基础数据
        CalcRecord::record($periodNum, '【基础数据】开始推送基础数据');
        $res = (new PushBaseDataToCalc($periodNum))->start();
        if (200 == $res['code']) {
            CalcRecord::record($periodNum, '【基础数据】基础数据完成推送');
        } else {
            Period::updatePeriodIsPreparing($periodNum, Period::NOT_PREPARING);
            CalcRecord::record($periodNum, '【基础数据】第' . $periodNum . '期基础数据推送失败，原因：' . $res['msg']);
            return false;
        }
        //todo 完成需要修改状态

        //通知结算系统生成期业绩
        CalcRecord::record($periodNum, '【期业绩】开始生成' . $periodNum . '期的期业绩');
        \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 1], 'PERIOD_NUM=' . $periodNum)->execute();
        //todo 完成需要修改状态

        //自动监听 拉取期业绩 并计算奖金
//        (new PullPerfDataFromCalc($periodNum))->start();
        //通知结算系统计算奖金
//        \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['IS_PREPARE' => 3], 'PERIOD_NUM=' . $periodNum)->execute();

        //自动监听 计算完成 自动拉取奖金结果并修改状态
//        (new PullCalcBonusData($period['PERIOD_NUM']))->start();
        return true;
    }

    public static function recordCalcAndProcessStatus($periodNum, $text)
    {
        Period::updatePeriodIsProcessing($periodNum, Period::NOT_PROCESSING);
        CalcRecord::record($periodNum, $text);
        return true;
    }

    /**推送基础数据
     * @param $taskKey
     * @return bool
     */
    public function actionPushData($taskKey): bool
    {
        $params    = Cache::getAsyncParams($taskKey);
        $periodNum = $params['periodNum'] ?? 0;
        CalcRecord::record($periodNum, '【基础数据】开始准备基础数据');
        //推送数据 状态已修改
        $res = (new PushBaseDataToCalc($periodNum))->start();
        if (200 == $res['code']) {
            self::recordCalcAndProcessStatus($periodNum, '【基础数据】基础数据已全部推送');
            return true;
        } else {
            self::recordCalcAndProcessStatus($periodNum, '【基础数据】基础数据推送失败,原因：' . substr($res['msg'],0,100));
            return false;
        }
    }

    /**拉取期业绩
     * @param $taskKey
     * @return bool
     */
    public function actionPullPeriod($taskKey): bool
    {
        $params    = Cache::getAsyncParams($taskKey);
        $periodNum = $params['periodNum'] ?? 0;
        CalcRecord::record($periodNum, '【期业绩】开始拉取期业绩数据');
        //推送数据 状态已修改
        $res = (new PullPerfDataFromCalc($periodNum))->start();
        if (200 == $res['code']) {
            self::recordCalcAndProcessStatus($periodNum, '【期业绩】期业绩数据已全部拉取');
            return true;
        } else {
            self::recordCalcAndProcessStatus($periodNum, '【期业绩】期业绩数据拉取失败,原因：' . substr($res['msg'],0,100));
            return false;
        }
    }

    /**拉取奖金数据
     * @param $taskKey
     * @return bool
     */
    public function actionPullBonus($taskKey): bool
    {
        $db        = self::CALC_DB_NAME;
        $params    = Cache::getAsyncParams($taskKey);
        $periodNum = $params['periodNum'] ?? 0;
        CalcRecord::record($periodNum, '【奖金计算】开始拉取'.$periodNum.'期奖金数据');
        $currentPeriod = Period::find()->where(['PERIOD_NUM' => $periodNum])
            ->asArray()->one();
        //推送数据 状态已修改
        $res = (new PullCalcBonusData($periodNum))->start();
        if (200 == $res['code']) {
            self::recordCalcAndProcessStatus($periodNum, '【奖金计算】'.$periodNum.'期奖金数据已全部拉取');
            \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['CALC_ID' => ''], 'PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM' => $periodNum])->execute();
            CalcOperation::closeOperation($currentPeriod['CALC_ID']);
            return true;
        } else {
            self::recordCalcAndProcessStatus($periodNum, '【奖金计算】'.$periodNum.'期奖金数据拉取失败,原因：' . $res['msg'] ?? '');
            \Yii::$app->$db->createCommand()->update('AR_PERIOD', ['CALC_ID' => ''], 'PERIOD_NUM=:PERIOD_NUM', ['PERIOD_NUM' => $periodNum])->execute();
            CalcOperation::closeOperation($currentPeriod['CALC_ID']);
            return false;
        }
    }

}
