<?php
namespace common\models\forms;

use common\helpers\Cache;
use common\helpers\Date;
use common\components\Model;
use common\helpers\Form;
use common\helpers\snowflake\SnowFake;
use common\helpers\user\Balance;
use common\helpers\user\Cash;
use common\helpers\user\Info;
use common\libs\logging\operate\AdminOperate;
use common\models\DealType;
use common\models\DecOrder;
use common\models\Order;
use common\models\OrderGoods;
use common\models\Period;
use common\models\ReceiveAddress;
use common\models\Region;
use common\models\ReturnOrder;
use common\models\ShopGoods;
use common\models\User;
use common\models\UserBonus;
use common\models\UserNetwork;
use common\models\UserWallet;
use yii\base\Exception;

/**
 * 删除订单
 */
class OrderDeleteForm extends Model
{
    public $orderSn;

    /**
     * @var Order
     */
    private $_model;

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['orderSn'], 'trim'],
            [['orderSn'], 'required'],
            [['orderSn'], 'checkOrderType'],
        ];
    }

    public function attributeLabels()
    {
        return [
            'orderSn' => '订单号',
        ];
    }

    /**
     * 指定校验场景
     * @return array
     */
    public function scenarios()
    {
        $parentScenarios =  parent::scenarios();
        $customScenarios = [
            // // 管理员发货
            // 'adminDelivery' => ['sn', 'expressCompany', 'orderTrackNo'],
            // // 会员确认收货
            // 'userConfirm' => ['sn', 'expressCompany', 'orderTrackNo'],
            // // 管理员修改订单状态
            // 'adminStatus' => ['sn', 'status'],
            // // 管理员修改备注
            // 'adminRemark' => ['sn', 'remark'],
            // // 会员下单
            // 'userOrder' => ['type','addressId', 'payType','goodsId','goodsNum', 'remark', 'payPassword'],
            // // 帮会员复消下单
            // 'reconsumeOrder' => ['type','userName', 'payType','goodsId','goodsNum', 'remark', 'payPassword','consignee','acceptMobile','province','city','county','detailaddress'],
        ];
        return array_merge($parentScenarios, $customScenarios);
    }

    public function returnOrder() {
        if(!$this->validate()){
            return null;
        }
        $sn = $this->orderSn;
        // 获取订单详情
        $orderInfo = Order::findUseDbCalc()
        ->select('ID,DEC_SN,SN,USER_ID,ORDER_TYPE,IS_DELETE,PAY_AMOUNT,PAY_TYPE,ORDER_AMOUNT,USER_NAME,PV,PAY_PV,PERIOD_NUM,PROVINCE,CITY,COUNTY,ADDRESS,CREATE_USER,ORDER_CATEGORY')
        ->where("SN=:SN", [':SN' => $sn])
        ->asArray()
        ->one();
        // 如果会员已经是锁定状态了,删除订单的时候,是否还要退还金额
        $db = \Yii::$app->db;
        $transaction = $db->beginTransaction();
        try {
            $userId = $orderInfo['USER_ID'];
            $decInfo = [];
            $isLock = 0 ; // 是否锁定会员单
            // 如果是注册订单,则删除订单并退还金额,然后再冻结用户
            if ($orderInfo['ORDER_TYPE'] == 'ZC') {
                // 查询报单数据,因为如果是报单,则要退还给报单中心
                $decInfo = DecOrder::findUseDbCalc()
                ->select('USER_ID,TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,ORI_LV,UPGRADE_LV')
                ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn])
                ->asArray()
                ->one();
                $userId = $decInfo['USER_ID'];
                // 删除报单
                $delDecOrder = DecOrder::updateAll(
                    ['IS_DEL'=>1, 'DELETED_AT'=>Date::nowTime()],
                    'ORDER_SN=:ORDER_SN',
                    ['ORDER_SN'=>$sn]
                );
                if (!$delDecOrder) {
                    $transaction->rollBack();
                    throw new Exception('删除报单失败，删除订单失败');
                }
                // 如果删除的是升级单,则需要回退用户的级别
                if ($decInfo['DETAIL_TYPE'] == 2) {
                    $oriLv = $decInfo['ORI_LV'];
                    $userModel = User::findOne(['ID' => $orderInfo['USER_ID']]);
                    $userModel->DEC_LV = $oriLv;
                    $userModel->UPDATED_AT = Date::nowTime();
                    if(!$userModel->save(false)) {
                        $transaction->rollBack();
                        throw new Exception('回退会员级别失败，删除订单失败');
                    }
                } else {
                    // 锁定用户
                    $userModel = User::findOne(['ID' => $orderInfo['USER_ID']]);
                    $userModel->STATUS = 0;
                    $userModel->STATUS_AT = Date::nowTime();
                    if(!$userModel->save(false)) {
                        $transaction->rollBack();
                        throw new Exception('锁定会员失败，删除订单失败');
                    }
                    $isLock = 1;
                }
            } else if ($orderInfo['ORDER_CATEGORY'] === 'STUDIO') {
                // 工作室复消：退款给下单人
                $createUser = User::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $orderInfo['CREATE_USER']]);
                if (!$createUser) {
                    $transaction->rollBack();
                    throw new Exception('删除订单失败。查找下单人失败');
                }
                $userId = $createUser['ID'];
            }
            // 公共的退钱,删除订单操作
            $delOrder = Order::updateAll(
                ['IS_DELETE'=>1, 'DELETED_AT'=>Date::nowTime()],
                'SN=:SN',
                ['SN'=>$sn]
            );
            if (!$delOrder) {
                $transaction->rollBack();
                throw new Exception('删除订单失败');
            }

            // 记录退还前的账户原资金
            $cash = $point = $bonus = $exchange = 0;
            $userBonus = UserBonus::findUseSlaves()
            ->select('BONUS,RECONSUME_POINTS,EXCHANGE_POINTS')
            ->where('USER_ID=:USER_ID', [':USER_ID' => $userId])
            ->asArray()
            ->one();
            if ($userBonus) {
                $point = $userBonus['RECONSUME_POINTS'];
                $bonus = $userBonus['BONUS'];
                $exchange = $userBonus['EXCHANGE_POINTS'];
            }
            $cashWallet = UserWallet::findOneAsArray('USER_ID=:USER_ID', [':USER_ID'=>$userId], 'CASH');
            if ($cashWallet) {
                $cash = $cashWallet['CASH'];
            }
            // 开始退钱,退积分等
            $payType = $orderInfo['PAY_TYPE']; // 支付方式
            $payAmount = $orderInfo['PAY_AMOUNT']; // 支付的金额
            //退还
            $amountResult = false;
            if($payType == 'cash') {
                $amountResult = Cash::changeUserCash($userId, 'CASH', +abs($payAmount), ['REMARK' => '删单退回', 'ORDER_SN' => $orderInfo['SN']]);
            } else if ($payType == 'exchange') {
                $amountResult = Balance::changeUserBonus($userId,'exchange_points', +abs($payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '删单退回', 'ORDER_SN' => $orderInfo['SN']]);
            } else{
                $amountResult = Balance::changeUserBonus($userId,'reconsume_points', +abs($payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '删单退回', 'ORDER_SN' => $orderInfo['SN']]);
            }
            if ($amountResult !== true) {
                $transaction->rollBack();
                throw new Exception('退还订单金额失败，删除订单失败');
            }
            $upgradeType = 0; // 升级单类型
            $returnLv = '';
            $oriLvs = '';
            if (!empty($decInfo)) {
                $upgradeType = $decInfo['UPGRADE_TYPE'];
                $returnLv = $decInfo['ORI_LV'];
                $oriLvs = $decInfo['UPGRADE_LV'];
            }
            // 退款成功,记录数据信息
            $periodObj = Period::instance();
            $nowPeriodNum = $periodObj->getNowPeriodNum();
            $returnOrderModel = new ReturnOrder();
            $returnOrderModel->ID = SnowFake::instance()->generateId();
            $returnOrderModel->SN = $sn;
            $returnOrderModel->DEC_SN = $orderInfo['DEC_SN'];
            $returnOrderModel->CREATE_AT = Date::nowTime();
            $returnOrderModel->ORDER_TYPE = $orderInfo['ORDER_TYPE'];
            $returnOrderModel->ORDER_AMOUNT = $orderInfo['ORDER_AMOUNT'];
            $returnOrderModel->PV = $orderInfo['PV'];
            $returnOrderModel->PAY_PV = $orderInfo['PAY_PV'];
            $returnOrderModel->PAY_AMOUNT = $orderInfo['PAY_AMOUNT'];
            $returnOrderModel->PAY_TYPE = $orderInfo['PAY_TYPE'];
            $returnOrderModel->USER_ID = $orderInfo['USER_ID'];
            $returnOrderModel->PERIOD_NUM = $nowPeriodNum;
            $returnOrderModel->ORDER_PERIOD_NUM = $orderInfo['PERIOD_NUM'];
            $returnOrderModel->UPGRADE_TYPE = $upgradeType;
            $returnOrderModel->USER_NAME = $orderInfo['USER_NAME'];
            $returnOrderModel->PROVINCE = $orderInfo['PROVINCE'];
            $returnOrderModel->CITY = $orderInfo['CITY'];
            $returnOrderModel->COUNTY = $orderInfo['COUNTY'];
            $returnOrderModel->ADDRESS = $orderInfo['ADDRESS'];
            $returnOrderModel->ADMIN_ID = \Yii::$app->user->id;
            $returnOrderModel->ORI_CASH = $cash;
            $returnOrderModel->ORI_BONUS = $bonus;
            $returnOrderModel->ORI_EXCHANGE_POINTS = $exchange;
            $returnOrderModel->ORI_RECONSUME_POINTS = $point;
            $returnOrderModel->ORI_DEC_LV = $oriLvs;
            $returnOrderModel->RETURN_DEC_LV = $returnLv;
            $returnOrderModel->IS_LOCKING = $isLock;
            if (!$returnOrderModel->save()) {
                $transaction->rollBack();
                $this->addErrors($returnOrderModel->getErrors());
                return false;
            }

            $transaction->commit();
        } catch(Exception $e) {
            $transaction->rollBack();
            $this->addError('add', $e->getMessage());
            return null;
        }

        return true;
    }

    // 判断订单类型
    public function checkOrderType($attribute) {
        $sn = $this->orderSn;
        $orderDetail = Order::findUseDbCalc()
        ->select('ID,DEC_SN,USER_ID,ORDER_TYPE,IS_DELETE,PERIOD_NUM')
        ->where("SN=:SN", [':SN' => $sn])
        ->asArray()
        ->one();
        if (empty($orderDetail)) {
            $this->addError($attribute, '未找到订单信息,订单编号为：'.$this->orderSn);
            return ;
        }
        if ($orderDetail['IS_DELETE'] == 1) {
            $this->addError($attribute, '订单已被删除,订单编号为'.$this->orderSn);
            return ;
        }
        // 已挂网或者挂网中的业绩期订单,不能进行删除操作
        $periodNum = $orderDetail['PERIOD_NUM'];
        $periodObj = Period::findOneAsArray(['PERIOD_NUM'=>$periodNum]);
        if (empty($periodObj)) {
            $this->addError($attribute, '订单对应业绩期不存在,订单编号为'.$this->orderSn.' 业绩期为：'.$periodNum);
            return ;
        }
        if ($periodObj['IS_SENT'] == 1) {
            $this->addError($attribute, '订单对应业绩期已挂网,订单编号为'.$this->orderSn.' 业绩期为：'.$periodNum);
            return ;
        }
        if ($periodObj['IS_SENDING'] == 1) {
            $this->addError($attribute, '订单对应业绩期正在挂网,订单编号为'.$this->orderSn.' 业绩期为：'.$periodNum);
            return ;
        }

        if ($orderDetail['ORDER_TYPE'] == 'ZC') {
            $decDetail = DecOrder::findUseDbCalc()
            ->select('TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,IS_DEL')
            ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn])
            ->asArray()
            ->one();
            if (empty($decDetail)) {
                $this->addError($attribute, '未获取到对应报单信息,订单编号为：'.$this->orderSn);
                return ;
            }
            if ($decDetail['IS_DEL'] == 1) {
                $this->addError($attribute, '对应报单信息已被删除,订单编号为：'.$this->orderSn);
                return ;
            }
            if ($decDetail['DETAIL_TYPE'] == 2) {
                // 如果删除升级单,则此升级单必须是用户的最后一个升级单
                $lastUpgradeOrder = DecOrder::findUseDbCalc()
                ->select('ORDER_SN')
                ->where("TO_USER_ID=:TO_USER_ID AND IS_DEL=0 AND DETAIL_TYPE=2", [':TO_USER_ID' => $decDetail['TO_USER_ID']])
                ->orderBy('CREATED_AT DESC')
                ->asArray()
                ->one();
                $lastUpgradeSn = $lastUpgradeOrder['ORDER_SN'];
                if ($sn != $lastUpgradeSn) {
                    $this->addError($attribute, '有更晚的订单，此订单不能删除,订单编号为：'.$this->orderSn);
                    return ;
                }
            } else {
                // 如果是注册单,但是这个用户存在升级单,则也不能进行删除
                $hasUpgradeOrder = DecOrder::findUseDbCalc()
                ->select('TO_USER_ID,DETAIL_TYPE,UPGRADE_TYPE,IS_DEL')
                ->where("TO_USER_ID=:TO_USER_ID AND IS_DEL=0 AND DETAIL_TYPE=2", [':TO_USER_ID' => $decDetail['TO_USER_ID']])
                ->asArray()
                ->one();
                if (!empty($hasUpgradeOrder)) {
                    $this->addError($attribute, '此注册报单，存在升级单，无法删除,订单编号为：'.$this->orderSn);
                    return ;
                }
                // 删除注册单,判断是否有复消单,如果存在复消单,需要先删除复消单
                $hasFxOrder = Order::findUseDbCalc()
                ->select('SN')
                ->where("USER_ID=:USER_ID AND IS_DELETE=0 AND ORDER_TYPE='FX'", [':USER_ID' => $decDetail['TO_USER_ID']])
                ->asArray()
                ->one();
                if (!empty($hasFxOrder)) {
                    $this->addError($attribute, '此注册报单，存在复消单，无法删除,订单编号为：'.$this->orderSn);
                    return ;
                }
            }
        }
        return true;
    }
}
