<?php


namespace JinDouYun\Model\Purchase;


use JinDouYun\Dao\Purchase\DSupplierWithdraw;
use JinDouYun\Model\Finance\MSupplierBalance;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\StatusCode;

class MSupplierWithdraw
{
    private $objDSupplierWithdraw;

    private $onlineUserId;

    private $onlineEnterpriseId;

    /**
     * MSupplierWithdraw constructor.
     * @param $onlineUserId
     * @param $onlineEnterpriseId
     * @throws \Exception
     */
    public function __construct($onlineUserId, $onlineEnterpriseId)
    {
        $this->onlineUserId = $onlineUserId;
        $this->onlineEnterpriseId = $onlineEnterpriseId;
        $this->objDSupplierWithdraw = new DSupplierWithdraw();
        $this->objDSupplierWithdraw->setTable('qianniao_supplier_withdraw_'.$this->onlineEnterpriseId);
    }

    public function add(array $params,int $supplierId): ResultWrapper
    {
        $objMSupplierBalance = new MSupplierBalance($this->onlineEnterpriseId,$this->onlineUserId);
        $supplierResult = $objMSupplierBalance->getSupplier($supplierId);
        if (!$supplierResult->isSuccess()){
            return ResultWrapper::fail($supplierResult->getData(),$supplierResult->getErrorCode());
        }
        $supplier = $supplierResult->getData();
        if ($supplier['money'] + $params['money'] > 0) {
            return ResultWrapper::fail('可提现余额不足', ErrorCode::$paramError);
        }
        $insert = [
            'no'             => createOrderSn(4,1,$this->onlineUserId),
            'supplierId'     => $supplierId,
            'supplierName'   => $supplier['title'],
            'type'           => $params['type'],
            'accountContent' => json_encode($params['accountContent']),
            'money'          => $params['money'],
            'auditStatus'    => StatusCode::$auditStatus['auditing'],
            'rate'           => 0,//抽成比率
            'fee'            => 0,//抽成金额
            'nowMoney'       => $params['money'],//预计到账金额
            'createTime'     => time(),
        ];

        $update = [
            'money' => bcadd($supplier['money'],$params['money'],2),
            'waitAuditWithdraw' => bcadd($supplier['waitAuditWithdraw'],$params['money'],2),
            'updateTime' => time()
        ];

        $this->objDSupplierWithdraw->beginTransaction();

        $result = $this->objDSupplierWithdraw->insert($insert);
        if ($result === false){
            $this->objDSupplierWithdraw->rollBack();
            return ResultWrapper::fail($this->objDSupplierWithdraw->error(),ErrorCode::$dberror);
        }

        $result = $objMSupplierBalance->updateSupplier($update,$supplierId);
        if (!$result->isSuccess()){
            $this->objDSupplierWithdraw->rollBack();
            return ResultWrapper::fail($result->getData(),$result->getErrorCode());
        }
        $this->objDSupplierWithdraw->commit();
        return ResultWrapper::success(true);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/18
     * Time: 6:08 下午
     * @param array $selectParams
     * @return ResultWrapper
     */
    public function getAll(array $selectParams): ResultWrapper
    {
        $fields = ' * ';
        $countField = ' COUNT(id) as total ';
        $whereSql = '';
        if (isset($selectParams['type']) && !empty($selectParams['type'])) {
            $whereSql .= ' AND `type` = ' . $selectParams['type'];
        }
        if (isset($selectParams['auditStatus']) && !empty($selectParams['auditStatus'])) {
            $whereSql .= ' AND auditStatus = ' . $selectParams['auditStatus'];
        }
        if (isset($selectParams['supplierId']) && !empty($selectParams['supplierId'])) {
            $whereSql .= ' AND supplierId = ' . $selectParams['supplierId'];
        }
        if (isset($selectParams['startTime']) && !empty($selectParams['startTime'])) {
            $whereSql .= ' AND createTime BETWEEN ' . $selectParams['startTime'] . ' AND ' . $selectParams['endTime'];
        }
        $countSql = 'SELECT ' . $countField . ' FROM ' . $this->objDSupplierWithdraw->get_Table() . ' WHERE id IS NOT NULL ' . $whereSql;
        $whereSql .= ' ORDER BY createTime DESC ';
        if (isset($selectParams['limit']) && !empty($selectParams['limit'])) {
            $whereSql .= ' LIMIT ' . $selectParams['offset'] . ',' . $selectParams['limit'];
        }
        $sql = 'SELECT ' . $fields . ' FROM ' . $this->objDSupplierWithdraw->get_Table() . ' WHERE id IS NOT NULL ' . $whereSql;;
        $dbResult = $this->objDSupplierWithdraw->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDSupplierWithdraw->error(), ErrorCode::$dberror);
        }
        $total = $this->objDSupplierWithdraw->query($countSql);
        foreach ($dbResult as &$value) {
            $value['accountContent'] = json_decode($value['accountContent'], true);
        }
        $return = [
            'data'  => $dbResult,
            'total' => isset($total[0]['total']) ? $total[0]['total'] : 0,
        ];
        return ResultWrapper::success($return);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/18
     * Time: 6:16 下午
     * @param int $id
     * @param int $status
     * @param $reason
     * @return ResultWrapper
     */
    public function updateAuditStatus(int $id, int $status,$reason): ResultWrapper
    {
        if (!in_array($status, array_keys(StatusCode::$auditStatus))) {
            return ResultWrapper::fail('状态不存在', ErrorCode::$notAllowAccess);
        }
        //查询当前记录
        $withdraw = $this->objDSupplierWithdraw->get($id);
        if ($withdraw === false) {
            return ResultWrapper::fail($this->objDSupplierWithdraw->error, ErrorCode::$dberror);
        }
        if (empty($withdraw)) {
            return ResultWrapper::fail('未获取到指定的记录', ErrorCode::$paramError);
        }

        $objMSupplierBalance = new MSupplierBalance($this->onlineEnterpriseId,$this->onlineUserId);
        $supplierResult = $objMSupplierBalance->getSupplier($withdraw['supplierId']);
        if (!$supplierResult->isSuccess()){
            return ResultWrapper::fail($supplierResult->getData(),$supplierResult->getErrorCode());
        }
        $supplier = $supplierResult->getData();

        $oldBalance = $supplier['money'];//可提现
        $oldWaitAuditWithdraw = $supplier['waitAuditWithdraw'];//提现等待审核
        $oldAuditWithdraw = $supplier['auditWithdraw'];//提现待入账金额
        $oldWithdraw = $supplier['withdraw'];//已提现金额
        $changeMoney = $withdraw['money'];//本次变动金额

        switch ($status){
            case StatusCode::$auditStatus['auditing']:
                //申请提现
                break;
            case StatusCode::$auditStatus['auditPass']:
                ////打款成功
                if (bcsub($oldAuditWithdraw, $changeMoney, 2) < 0) {
                    return ResultWrapper::fail('待入账金额不足', ErrorCode::$paramError);
                }
                $updateMap = [
                    'id' => $supplier['id'],
                    'updateTime' => time(),
                    'auditWithdraw' => bcsub($oldAuditWithdraw,$changeMoney,2),
                    'withdraw' => bcadd($oldWithdraw,$changeMoney,2),
                ];
                break;
            case StatusCode::$auditStatus['auditNotPass']:
                //提现审核拒绝,回到余额
                if (bcsub($oldWaitAuditWithdraw, $changeMoney, 2) < 0) {
                    return ResultWrapper::fail('待审核金额不足', ErrorCode::$paramError);
                }
                $updateMap = [
                    'id' => $supplier['id'],
                    'updateTime' => time(),
                    'money' => bcsub($oldBalance,$changeMoney,2),
                    'waitAuditWithdraw' => bcsub($oldWaitAuditWithdraw,$changeMoney,2),
                ];
                break;
            case StatusCode::$auditStatus['auditIng']:
                //等待打款,审核成功
                if (bcsub($oldWaitAuditWithdraw, $changeMoney, 2) < 0) {
                    return ResultWrapper::fail('待审核金额不足', ErrorCode::$paramError);
                }
                $updateMap = [
                    'id' => $supplier['id'],
                    'updateTime' => time(),
                    'waitAuditWithdraw' => bcsub($oldWaitAuditWithdraw,$changeMoney,2),
                    'auditWithdraw' => bcadd($oldAuditWithdraw,$changeMoney,2),
                ];
                break;
            default:
                return ResultWrapper::fail('状态值有误', ErrorCode::$paramError);
                break;
        }

        $updateData = [
            'auditStatus' => $status,
            'updatetime'  => time(),
            'reason' => $reason,
        ];

        // 审核通过时间
        if ($status == StatusCode::$auditStatus['auditIng']) {
            $updateData['auditTime'] = time();
        }

        // 打款完成时间
        if ($status == StatusCode::$auditStatus['auditIng']) {
            $updateData['payTime'] = time();
        }

        $this->objDSupplierWithdraw->beginTransaction();
        $result = $this->objDSupplierWithdraw->update($updateData,$id);
        if ($result === false){
            $this->objDSupplierWithdraw->rollBack();
            return ResultWrapper::fail($this->objDSupplierWithdraw->error(),ErrorCode::$dberror);
        }

        $updateResult = $objMSupplierBalance->updateSupplier($updateMap,$supplier['id']);
        if (!$updateResult->isSuccess()){
            $this->objDSupplierWithdraw->rollBack();
            return ResultWrapper::fail($updateResult->getData(),$updateResult->getErrorCode());
        }
        $this->objDSupplierWithdraw->commit();
        return ResultWrapper::success(true);
    }

}