<?php

namespace common\models;

use common\helpers\Cache;
use common\helpers\Date;
use common\helpers\Tool;
use common\helpers\user\Info;
use Yii;

/**
 * This is the model class for table "{{%WITHDRAW}}".
 *
 * @property string $ID
 * @property string $SN 单号
 * @property string $USER_ID 会员ID
 * @property string $ID_CARD 身份证号
 * @property int $WITHDRAW_PERIOD_NUM 提现期数
 * @property int $WITHDRAW_YEAR 提现年份
 * @property int $WITHDRAW_MONTH 提现月份
 * @property int $PAY_TYPE 付款类型
 * @property int $IS_AUTO_WITHDRAW 是否自动提现
 * @property string $AMOUNT 提现金额
 * @property string $FEES 提现手续费
 * @property string $REAL_AMOUNT 实际提现金额
 * @property string $INVOICE_ID 发票ID
 * @property string $REAL_NAME 会员姓名
 * @property string $OPEN_BANK 开户行
 * @property string $BANK_ADDRESS 银行地址
 * @property string $BANK_NO 银行账号
 * @property int $BANK_PROVINCE 银行省份
 * @property int $BANK_CITY 银行城市
 * @property int $BANK_COUNTY 银行地区
 * @property string $P_MONTH 表分区标识
 * @property int $AUDIT_STATUS 审核状态
 * @property string $REMARK 备注
 * @property string $UPDATE_ADMIN 修改管理员
 * @property string $UPDATE_REMARK 修改备注
 * @property string $AUDIT_ADMIN 审核管理员
 * @property int $CREATED_AT 创建时间
 * @property int $UPDATED_AT 修改时间
 * @property int $AUDITED_AT 审核时间
 * @property int $PLAN_PAID_AT 预计付款时间
 * @property int $PAID_AT 付款时间
 * @property string $PAID_FAIL_REMARK 付款失败备注
 * @property int $PAID_FAIL_AT 付款失败时间
 * @property string $BACK_REMARK 提现退回备注
 * @property int $BACK_FAIL_AT 提现退回时间
 */
class Withdraw extends \common\components\ActiveRecord {
    const TYPE_MANUAL = 0;      // 手动提现
    const TYPE_AUTO = 1;        // 自动提现
    const TYPE_ADMIN = 2;       // 后台管理员

    //付款类型
    const PAY_TYPE_NO_INVOICE = 0;
    const PAY_TYPE_NEED_INVOICE = 1;

    const STATUS_APPLIED = 0;       // 已申请
//    const STATUS_INVOICED = 1;      // 已传票
    const STATUS_AUDITED = 2;       // 已审核
    const STATUS_WAIT_PAID = 3;     // 待付款
    const STATUS_PAID_FALSE = 4;    // 付款失败
    const STATUS_REFUSED = 5;       // 已拒绝
    const STATUS_PAID = 6;          // 已付款
    const STATUS_RETURN = 7;        // 提现退回

    const STATUS_NAME = [
        self::STATUS_APPLIED => '提现待审核',
//        self::STATUS_INVOICED => '提现待审核',
        self::STATUS_AUDITED => '提现已审核',
        self::STATUS_WAIT_PAID => '提现待付款',
        self::STATUS_PAID_FALSE => '付款失败',
        self::STATUS_REFUSED => '已拒绝',
        self::STATUS_PAID => '提现已付款',
        self::STATUS_RETURN => '已退回',
    ];

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

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['USER_ID', 'P_MONTH', 'CREATED_AT', 'PLAN_PAID_AT'], 'required'],
            [['WITHDRAW_PERIOD_NUM', 'WITHDRAW_YEAR', 'WITHDRAW_MONTH', 'IS_AUTO_WITHDRAW', 'BANK_PROVINCE', 'BANK_CITY', 'BANK_COUNTY', 'AUDIT_STATUS', 'CREATED_AT', 'UPDATED_AT', 'AUDITED_AT', 'PLAN_PAID_AT', 'PAID_AT', 'PAID_FAIL_AT', 'BACK_FAIL_AT', 'PAY_TYPE'], 'integer'],
            [['AMOUNT','FEES','REAL_AMOUNT'], 'number'],
            [['ID', 'SN', 'USER_ID', 'INVOICE_ID', 'OPEN_BANK', 'BANK_NO', 'UPDATE_ADMIN', 'AUDIT_ADMIN'], 'string', 'max' => 32],
            [['ID_CARD'], 'string', 'max' => 20],
            [['REAL_NAME', 'BANK_ADDRESS'], 'string', 'max' => 255],
            [['REMARK', 'UPDATE_REMARK', 'PAID_FAIL_REMARK', 'BACK_REMARK'], 'string', 'max' => 4000],
            [['ID'], 'unique'],
            [['SN'], 'unique'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'ID' => 'ID',
            'SN' => '单号',
            'USER_ID' => '会员ID',
            'ID_CARD' => '身份证号',
            'WITHDRAW_PERIOD_NUM' => '提现期数',
            'WITHDRAW_YEAR' => '提现年份',
            'WITHDRAW_MONTH' => '提现月份',
            'PAY_TYPE' => '付款类型',
            'IS_AUTO_WITHDRAW' => '是否自动提现',
            'AMOUNT' => '提现金额',
            'FEES' => '提现手续费',
            'REAL_AMOUNT' => '实际提现金额',
            'INVOICE_ID' => '发票ID',
            'REAL_NAME' => '会员姓名',
            'OPEN_BANK' => '开户行',
            'BANK_ADDRESS' => '银行地址',
            'BANK_NO' => '银行账号',
            'BANK_PROVINCE' => '银行省份',
            'BANK_CITY' => '银行城市',
            'BANK_COUNTY' => '银行地区',
            'P_MONTH' => '表分区标识',
            'AUDIT_STATUS' => '审核状态',
            'REMARK' => '备注',
            'UPDATE_ADMIN' => '修改管理员',
            'UPDATE_REMARK' => '修改备注',
            'AUDIT_ADMIN' => '审核管理员',
            'CREATED_AT' => '创建时间',
            'UPDATED_AT' => '修改时间',
            'AUDITED_AT' => '审核时间',
            'PLAN_PAID_AT' => '预计付款时间',
            'PAID_AT' => '付款时间',
            'PAID_FAIL_REMARK' => '付款失败备注',
            'PAID_FAIL_AT' => '付款失败时间',
            'BACK_REMARK' => '提现退回备注',
            'BACK_FAIL_AT' => '提现退回时间',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getOpenBank() {
        return $this->hasOne(OpenBank::class, ['BANK_CODE' => 'BANK_CODE']);
    }

    /**
     * 获取提现相关期数，目前按照直接取当月第一期来实现
     * @param $nowTime
     * @return array
     */
    public static function getPeriod($nowTime) {
        $period = Period::instance();
        $year = $period->getNowYear();
        $month = $period->getNowMonth();
        $yearMonth = $period->getNowYearMonth();
        $thisMonth = Period::getPeriodNumRangeFromMonth($year, $month);
        $period->setPeriodNum($thisMonth['min']);
        $endTime = $period->getNowPeriodEnd();
        return ['nowPeriodNum' => $thisMonth['min'], 'nowYear' => $year, 'nowMonth' => $month, 'yearMonth'=>$yearMonth, 'endTime' => $endTime];
    }

    /**
     * 是否存在待审核的提现
     * @param $userId
     * @return bool
     */
    public static function existWaitAudit($userId) {
        $noTwiceWithdraw = [self::STATUS_APPLIED, self::STATUS_WAIT_PAID, self::STATUS_PAID_FALSE];
        $noTwiceWithdrawStr = implode("','", $noTwiceWithdraw);
        $noTwiceWithdrawStr = "'" . $noTwiceWithdrawStr . "'";
        if ($status = static::findOneAsArray('USER_ID=:USER_ID AND AUDIT_STATUS IN (' . $noTwiceWithdrawStr . ')', [':USER_ID' => $userId], 'AUDIT_STATUS')) {
            return self::STATUS_NAME[$status['AUDIT_STATUS']];
        } else {
            return '';
        }
    }

    /**
     * 会员本月是否提现
     * @param $uid
     * @return bool
     */
    public static function hasThisMonthWithdraw($uid) {
        $period = Period::instance();
        $idCard = Info::getIdCardByUserId($uid);
        if ($idCard) {
            if (static::find()->where('ID_CARD=:ID_CARD AND WITHDRAW_YEAR=:WITHDRAW_YEAR AND WITHDRAW_MONTH=:WITHDRAW_MONTH AND AUDIT_STATUS!=:AUDIT_STATUS', [':ID_CARD' => $idCard, ':WITHDRAW_YEAR' => $period->getNowYear(), ':WITHDRAW_MONTH' => $period->getNowMonth(), ':AUDIT_STATUS' => self::STATUS_RETURN])->exists()) {
                return true;
            }
        } else {
            if (static::find()->where('USER_ID=:USER_ID AND WITHDRAW_YEAR=:WITHDRAW_YEAR AND WITHDRAW_MONTH=:WITHDRAW_MONTH AND AUDIT_STATUS!=:AUDIT_STATUS', [':USER_ID' => $uid, ':WITHDRAW_YEAR' => $period->getNowYear(), ':WITHDRAW_MONTH' => $period->getNowMonth(), ':AUDIT_STATUS' => self::STATUS_RETURN])->exists()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否可提现
     * @return bool
     */
    public static function allowWithdraw() {
        return true;//@todo 上线时删除
        $period = Period::instance();
        $year = $period->getNowYear();
        $month = $period->getNowMonth();
        $thisMonth = Period::getPeriodNumRangeFromMonth($year, $month);
        $periodNum = $period->getNowPeriodNum();

        if ($periodNum == $thisMonth['min']) {
            //上月是否已挂网
            $lastMonth = $period->getLastMonth();
            $lastPeriodPoint = Period::getPeriodPointFromMonth($lastMonth['year'], $lastMonth['month']);
            if ($lastPeriodPoint && $lastPeriodPoint['SENT_AT'] > 0 && Date::nowTime() > $lastPeriodPoint['SENT_AT']) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否到了自动期限的日期
     * @return bool
     */
    public static function allowAutoWithdraw() {
        $period = Period::instance();
        $year = $period->getNowYear();
        $month = $period->getNowMonth();
        $thisMonth = Period::getPeriodNumsFromMonth($year, $month);
        $periodNum = $period->getNowPeriodNum();
        //结算月第一周封期后
        if ($periodNum == $thisMonth[1]['PERIOD_NUM']) {
            //上月是否已挂网
            $lastMonth = $period->getLastMonth();
            $lastPeriodPoint = Period::getPeriodPointFromMonth($lastMonth['year'], $lastMonth['month']);
            if ($lastPeriodPoint && $lastPeriodPoint['SENT_AT'] > 0 && Date::nowTime() > $lastPeriodPoint['SENT_AT']) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取本月提现金额
     * @param $uid
     * @return string
     */
    public static function getThisMonthWithdraw($uid) {
        $period = Period::instance();
        $withdraw = static::find()->select('SUM(AMOUNT) AS sums')->where('USER_ID=:USER_ID AND WITHDRAW_YEAR=:WITHDRAW_YEAR AND WITHDRAW_MONTH=:WITHDRAW_MONTH', [':USER_ID' => $uid, ':WITHDRAW_YEAR' => $period->getNowYear(), ':WITHDRAW_MONTH' => $period->getNowMonth()])->asArray()->one();
        return tool::formatPrice($withdraw['sums'] ? $withdraw['sums'] : 0);
    }

    /**
     * 获取本年提现金额
     * @param $uid
     * @return string
     */
    public static function getThisYearWithdraw($uid) {
        $period = Period::instance();
        $withdraw = static::find()->select('SUM(AMOUNT) AS sums')->where('USER_ID=:USER_ID AND WITHDRAW_YEAR=:WITHDRAW_YEAR', [':USER_ID' => $uid, ':WITHDRAW_YEAR' => $period->getNowYear()])->asArray()->one();
        return tool::formatPrice($withdraw['sums'] ? $withdraw['sums'] : 0);
    }


    /**
     * 调整会员的自动提现状态
     * @param $userId
     * @param int $isAuto
     */
    public static function setAutoWithdraw($userId, $isAuto = 1) {
        UserInfo::updateAll(['IS_AUTO_WITHDRAW' => $isAuto], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
    }

    /**
     * 银行信息
     * @param $row
     * @param $baseInfo
     * @return array
     */
    public static function getBankInfo($row, $baseInfo) {
        $regionConfig = Cache::getRegionConfig();
        $data = ['REAL_NAME' => '', 'OPEN_BANK' => '', 'BANK_PROVINCE' => '', 'BANK_CITY' => '', 'BANK_COUNTY' => '', 'BANK_ADDRESS' => '', 'BANK_NO' => '', 'BANK_UPDATED_AT' => $baseInfo['BANK_UPDATED_AT']];
        if ($row['AUDIT_STATUS'] == self::STATUS_PAID) {
            $data['REAL_NAME'] = $row['REAL_NAME'];
            $data['OPEN_BANK'] = $row['OPEN_BANK'];
            $data['BANK_PROVINCE'] = $row['BANK_PROVINCE'];
            $data['BANK_CITY'] = $row['BANK_CITY'];
            $data['BANK_COUNTY'] = $row['BANK_COUNTY'];
            $data['BANK_ADDRESS'] = $row['BANK_ADDRESS'];
            $data['BANK_NO'] = $row['BANK_NO'];

        } else {
            //公司
            if ($row['REG_TYPE'] == '758BF69C25C3422AA7743936BC77EE64') {
                $companyBank = CompanyBank::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $row['USER_ID']]);
                $data['REAL_NAME'] = $companyBank['OPEN_NAME'];
                $data['OPEN_BANK'] = $companyBank['OPEN_BANK'];
                $data['BANK_PROVINCE'] = $companyBank['BANK_PROVINCE'];
                $data['BANK_CITY'] = $companyBank['BANK_CITY'];
                $data['BANK_COUNTY'] = $companyBank['BANK_COUNTY'];
                $data['BANK_ADDRESS'] = $companyBank['BANK_ADDRESS'];
                $data['BANK_NO'] = $companyBank['BANK_NO'];
                $data['BANK_UPDATED_AT'] = $companyBank['UPDATED_AT'];
            } else {
                $data['REAL_NAME'] = $baseInfo['REAL_NAME'];
                $data['OPEN_BANK'] = $baseInfo['OPEN_BANK'];
                $data['BANK_PROVINCE'] = $baseInfo['BANK_PROVINCE'];
                $data['BANK_CITY'] = $baseInfo['BANK_CITY'];
                $data['BANK_COUNTY'] = $baseInfo['BANK_COUNTY'];
                $data['BANK_ADDRESS'] = $baseInfo['BANK_ADDRESS'];
                $data['BANK_NO'] = $baseInfo['BANK_NO'];
            }
        }
        $data['BANK_PROVINCE_NAME'] = $baseInfo['BANK_PROVINCE'] ? $regionConfig[$baseInfo['BANK_PROVINCE']]['REGION_NAME'] : '';
        $data['BANK_CITY_NAME'] = $baseInfo['BANK_CITY'] ? $regionConfig[$baseInfo['BANK_CITY']]['REGION_NAME'] : '';
        $data['BANK_COUNTY_NAME'] = $baseInfo['BANK_COUNTY'] ? $regionConfig[$baseInfo['BANK_COUNTY']]['REGION_NAME'] : '';
        $data['OPEN_BANK_NAME'] = $baseInfo['OPEN_BANK'] ? OpenBank::getCnName($baseInfo['OPEN_BANK']) : '';
        return $data;
    }

    /**
     * 判断提现状态
     * @param $sn
     * @param $nowStatus
     * @param $toStatus
     * @return string
     */
    public static function chkAuditStatus($sn, $nowStatus, $toStatus) {
        $statusName = self::STATUS_NAME;
        $msg = '提现单' . $sn . '当前状态为【' . $statusName[$nowStatus] . '】，无法设置为【' . $statusName[$toStatus] . '】';
        switch ($toStatus) {
            //已审核
            case Withdraw::STATUS_AUDITED:
                if ($nowStatus == Withdraw::STATUS_APPLIED) {
                    $msg = '';
                }
                break;
            //待付款
            case Withdraw::STATUS_WAIT_PAID:
                if ($nowStatus == Withdraw::STATUS_AUDITED || $nowStatus == Withdraw::STATUS_PAID_FALSE) {
                    $msg = '';
                }
                break;
            //已付款
            case Withdraw::STATUS_PAID:
                if ($nowStatus == Withdraw::STATUS_WAIT_PAID) {
                    $msg = '';
                }
                break;
            //付款失败
            case Withdraw::STATUS_PAID_FALSE:
                if ($nowStatus == Withdraw::STATUS_PAID) {
                    $msg = '';
                }
                break;
            //提现退回
            case Withdraw::STATUS_RETURN:
                if ($nowStatus == Withdraw::STATUS_APPLIED  || $nowStatus == Withdraw::STATUS_AUDITED || Withdraw::STATUS_WAIT_PAID) {
                    $msg = '';
                }
                break;
            //审核拒绝
            case Withdraw::STATUS_REFUSED:
                if ($nowStatus == Withdraw::STATUS_APPLIED) {
                    $msg = '';
                }
                break;
            default:
        }
        return $msg;
    }

    /**
     * 按提现状态返回总和
     * @param $userId
     * @param int $type
     * @return mixed
     */
    public static function getWithdrawTotal($userId, $type = self::STATUS_PAID) {
        $total = self::find()->where('USER_ID=:USER_ID AND AUDIT_STATUS=:AUDIT_STATUS', [':USER_ID' => $userId, ':AUDIT_STATUS' => $type])->sum('AMOUNT');
        return $total ? $total : '0.00';
    }

    /**
     * 按提现状态返回所有会员总和
     * @param int $type
     * @return mixed
     */
    public static function getAllWithdrawTotal($type = self::STATUS_PAID) {
        $total = self::find()->where('AUDIT_STATUS=:AUDIT_STATUS', [':AUDIT_STATUS' => $type])->sum('AMOUNT');
        return $total ? $total : '0.00';
    }

}
