<?php

namespace common\models;

use common\helpers\Date;
use common\helpers\Tool;
use Yii;
use yii\db\Exception;

/**
 * This is the model class for table "{{%PERIOD}}".
 *
 * @property string $ID
 * @property int $PERIOD_NUM 期数
 * @property int $CALC_MONTH 所在结算月
 * @property int $CALC_YEAR 所在结算年
 * @property int $START_TIME 期数开始时间戳
 * @property int $END_TIME 期数结束时间戳
 * @property int $IS_MONTH 是否结算月节点
 * @property int $IS_YEAR 是否结算年节点
 * @property int $IS_CLOSED 是否已封期
 * @property int $IS_PERFED 是否已生成业绩单
 * @property int $IS_CALCULATED 是否已结算
 * @property int $IS_SENT 是否已发放
 * @property int $IS_PERFING 是否正在生成业绩单
 * @property int $IS_CALCING 是否正在计算状态
 * @property int $IS_SENDING 是否正在挂网状态
 * @property int $CALC_PERCENT 结算进度
 * @property int $SENT_PERCENT 发放进度
 * @property string $PERF_ADMIN_ID 生成业绩单管理员
 * @property string $CLOSE_ADMIN_ID 手动封期管理员ID
 * @property string $CALC_ADMIN_ID 结算管理员ID
 * @property string $SENT_ADMIN_ID 发放管理员ID
 * @property int $CLOSED_AT 发放管理员ID
 * @property int $PERF_STARTED_AT 生成业绩单开始时间
 * @property int $PERFED_AT 生成业绩单结束时间
 * @property int $CALCULATE_STARTED_AT 结算开始时间
 * @property int $CALCULATED_AT 结算完成时间
 * @property int $SEND_STARTED_AT 发放开始时间
 * @property int $SENT_AT 发放完成时间
 * @property int $CREATED_AT 创建时间
 */
class Period extends \common\components\ActiveRecord
{
    const CALCULATE_NONE = 0;
    const CALCULATE_FINISH = 1;
    const CALCULATE_FAIL = 2;

    const SEND_NONE = 0;
    const SEND_FINISH = 1;
    const SEND_FAIL = 2;

    const PERF_NONE = 0;
    const PERF_FINISH = 1;
    const PERF_FAIL = 2;

    const SYSTEM_START_PERIOD_NUM = 100;

    public $nowPeriodArr = null;
    public $periodNum = null;
    public $periodArr = null;

    public function init()
    {
        parent::init();
    }

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%PERIOD}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['PERIOD_NUM', 'CALC_MONTH', 'CALC_YEAR', 'START_TIME', 'END_TIME', 'CREATED_AT'], 'required'],
            [['PERIOD_NUM', 'CALC_MONTH', 'CALC_YEAR', 'START_TIME', 'END_TIME', 'IS_MONTH', 'IS_YEAR', 'IS_PERFED', 'IS_CALCULATED', 'IS_SENT', 'IS_PERFING', 'IS_CALCING', 'CALC_PERCENT', 'CLOSED_AT', 'PERF_STARTED_AT', 'PERFED_AT', 'CALCULATE_STARTED_AT', 'CALCULATED_AT','CREATED_AT'], 'integer'],
            [['ID'], 'string', 'max' => 32],
            [['PERIOD_NUM'], 'unique'],
            [['ID'], 'unique'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'ID' => 'ID',
            'PERIOD_NUM' => '期数',
            'CALC_MONTH' => '所在结算月',
            'CALC_YEAR' => '所在结算年',
            'START_TIME' => '期数开始时间戳',
            'END_TIME' => '期数结束时间戳',
            'IS_MONTH' => '是否结算月节点',
            'IS_YEAR' => '是否结算年节点',
            'IS_PERFED' => '是否已生成业绩单',
            'IS_CALCULATED' => '是否已结算',
            'IS_PERFING' => '是否正在生成业绩单',
            'IS_CALCING' => '是否正在计算状态',
            'CALC_PERCENT' => '结算进度',
            'CLOSED_AT' => '发放管理员ID',
            'PERF_STARTED_AT' => '生成业绩单开始时间',
            'PERFED_AT' => '生成业绩单结束时间',
            'CALCULATE_STARTED_AT' => '结算开始时间',
            'CALCULATED_AT' => '结算完成时间',
            'CREATED_AT' => '创建时间',
        ];
    }

    /**
     * 期数赋值给属性
     * @param int $periodNum
     * @return array|null|\yii\db\ActiveRecord
     */
    public function setPeriodNum($periodNum = null){
        if (empty($periodNum)) {
            $this->nowPeriodArr = static::find()
                ->where(' 1=1')
                ->orderBy('PERIOD_NUM DESC')
                ->asArray()
                ->one();
            if (empty($this->nowPeriodArr)) {

                return false;
            }
            $this->periodArr = $this->nowPeriodArr;
            $periodNum = $this->nowPeriodArr['PERIOD_NUM'];
        } else {
            $this->periodArr = static::findOneAsArray(
                'PERIOD_NUM=:PERIOD_NUM', 
                [':PERIOD_NUM'=>$periodNum]
            );
            if (empty($this->periodArr)) {

                return false;
            }
        }
        $this->periodNum = $periodNum;

        return $this->periodArr;
    }

    // 通过期数,获取此期数据
    public static function getInfoByPeriodNum($periodNum) {
        
        return static::findOneAsArray(['PERIOD_NUM'=>$periodNum]);
    }

    /**
     * 是否存在所传期数
     * @param int $periodNum
     * @return bool
     */
    public static function isExistsPeriodNum(int $periodNum){
        return static::find()->where(['PERIOD_NUM'=>$periodNum])->exists();
    }

    /**
     * 获取当前期的开始时间
     * @return int
     */
    public function getNowPeriodStart(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['START_TIME'];
        } else {
            return Date::nowTime();
        }
    }

    /**
     * 获取当前期的结束时间
     * @return int
     */
    public function getNowPeriodEnd(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['END_TIME'];
        } else {
            return Date::nowTime();
        }
    }

    /**
     * 获取当前所在的结算月
     * @return int
     */
    public function getNowMonth(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['CALC_MONTH'];
        } else {
            return 0;
        }
    }

    /**
     * 获取当前期数所在结算年
     * @return int
     */
    public function getNowYear(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['CALC_YEAR'];
        } else {
            return 0;
        }
    }

    /**
     * 当前期数所在年月
     * @return int|string
     */
    public function getNowYearMonth(){
        $this->setPeriodNum();
        if($this->nowPeriodArr){
            return $this->nowPeriodArr['CALC_YEAR'].Tool::numFix($this->nowPeriodArr['CALC_MONTH']);
        } else {
            return 0;
        }
    }

    /**
     * 获取期数所在的结算月
     * @param int $periodNum
     * @return mixed
     * @throws Exception
     */
    public function getMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['CALC_MONTH'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 获取期数所在的结算年
     * @param $periodNum
     * @return mixed
     * @throws Exception
     */
    public function getYear($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['CALC_YEAR'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 期数所在年月
     * @param $periodNum
     * @return string
     * @throws Exception
     */
    public function getYearMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['CALC_YEAR'].Tool::numFix($period['CALC_MONTH'], 2);
        } else {
            throw new Exception('期数不存在'.$periodNum);
        }
    }

    /**
     * 所传年、月所有期数的数量
     * @param $year
     * @param $month
     * @return int
     */
    public function getYearMonthAllPeriodNumCount($year, $month){
        return Period::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->count(1);
    }

    /**
     * 所传年、月所有期数
     * @param $year
     * @param $month
     * @return array
     */
    public function getYearMonthAllPeriod($year, $month){
        return Period::find()->select('PERIOD_NUM')->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->column();
    }

    /**
     * 是否是结算月节点
     * @param $periodNum
     * @return mixed
     * @throws Exception
     */
    public function isCalcMonth($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['IS_MONTH'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 是否是结算年节点
     * @param $periodNum
     * @return mixed
     * @throws Exception
     */
    public function isCalcYear($periodNum = null){
        $period = $this->setPeriodNum($periodNum);
        if($period){
            return $period['IS_YEAR'];
        } else {
            throw new Exception('期数不存在');
        }
    }

    /**
     * 返回所传结算月包含的所有期数
     * @param $year
     * @param $month
     * @return array|\yii\db\ActiveRecord[]
     */
    public static function getPeriodNumsFromMonth($year, $month){
        return static::find()->select('PERIOD_NUM')->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH', [':CALC_YEAR'=>$year, ':CALC_MONTH'=>$month])->orderBy('PERIOD_NUM ASC')->asArray()->all();
    }

    /**
     * 获取所传结算月的最小期数和最大期数
     * @param $year
     * @param $month
     * @return array
     */
    public static function getPeriodNumRangeFromMonth($year, $month){
        $allPeriod = self::getPeriodNumsFromMonth($year, $month);
        $tempPeriod = [];
        foreach($allPeriod as $period){
            $tempPeriod[] = $period['PERIOD_NUM'];
        }
        if(!$tempPeriod){
            return null;
        }
        $minPeriod = min($tempPeriod);
        $maxPeriod = max($tempPeriod);
        return ['min'=>$minPeriod, 'max'=>$maxPeriod];
    }

    /**
     * 返回结算月的节点期数
     * @param $year
     * @param $month
     * @return mixed|null
     */
    public static function getPeriodNumPointFromMonth($year, $month) {
        $data = static::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH AND IS_MONTH=1', [':CALC_YEAR'=>$year, ':CALC_MONTH' => $month])->asArray()->one();
        if($data) return $data['PERIOD_NUM'];
        else return null;
    }

    /**
     * 返回结算月的节点期
     * @param $year
     * @param $month
     * @return mixed|null
     */
    public static function getPeriodPointFromMonth($year, $month) {
        $data = static::find()->where('CALC_YEAR=:CALC_YEAR AND CALC_MONTH=:CALC_MONTH AND IS_MONTH=1', [':CALC_YEAR'=>$year, ':CALC_MONTH' => $month])->asArray()->one();
        if($data) return $data;
        else return null;
    }

    // 奖金计算,更新业绩表,进度百分比
    public static function updatePercent($percent, $periodNum) {
        $result = Period::updateAll(
            ['PERF_PERCENT' => $percent], 
            'PERIOD_NUM=:PERIOD_NUM', 
            [':PERIOD_NUM' => $periodNum]
        );

        return $result;
    }

    /**
     * 更新计算进度
     */
    public static function updateCalcProcess($perpare, $periodNum) {
        $result = Period::updateAll(
            ['IS_PREPARE' => $perpare], 
            'PERIOD_NUM=:PERIOD_NUM', 
            [':PERIOD_NUM' => $periodNum]
        );

        return $result;
    }

    // 通过业绩期和用户id,获取蓝星的最新级别信息
    public static function userLastEmpLv($userId, $periodNum) {
        // 先判断此期是否是月节点
        $nowPeriod = Period::find()
        ->where('PERIOD_NUM=:PERIOD_NUM', [':PERIOD_NUM'=>$periodNum])
        ->asArray()
        ->one();
        if ($nowPeriod['IS_MONTH'] == 1) {
            $bsMonthPeriod = $nowPeriod['PERIOD_NUM'];
        } else {
            $forwardMonthPeriod = Period::find()
            ->where('IS_MONTH=1 AND PERIOD_NUM<:PERIOD_NUM', [':PERIOD_NUM'=>$periodNum])
            ->orderBy('PERIOD_NUM DESC')
            ->asArray()
            ->one();
            $bsMonthPeriod = $forwardMonthPeriod['PERIOD_NUM'];
        }
        $blueBsInfo = CalcBonusBS::findOneAsArray(
            'PERIOD_NUM=:PERIOD_NUM  AND USER_ID=:USER_ID', 
            [':PERIOD_NUM'=>$bsMonthPeriod, ':USER_ID'=>$userId]
        );
        if (!empty($blueBsInfo)) {
            $bsEmpLv = $blueBsInfo['LEVEL_ID']; // 当前蓝星奖计算(即管理奖) 的等级
        } else {
            $bsEmpLv = EmployLevel::NO_LEVEL_ID;
        }

        return $bsEmpLv;
    }
}
