<?php
/**
 * MemWallet.php UTF-8
 * 玩家钱包
 *
 * @date    : 2018/5/18 22:14
 *
 * @license 这不是一个自由软件,未经授权不许任何使用和传播。
 * @author  : wuyonghong <wyh@huosdk.com>
 * @version : HUOSDK 8.0
 */

namespace huo\controller\member;

use huo\controller\common\Base;
use huo\controller\wallet\GmCache;
use huo\controller\wallet\WalletRequest;
use huo\model\finance\GmBackModel;
use huo\model\finance\GmChargeModel;
use huo\model\finance\GmOrderModel;
use huo\model\finance\PtbBackModel;
use huo\model\finance\PtbChargeModel;
use huo\model\finance\PtbOrderModel;
use huolib\constant\OrderConst;
use huolib\constant\SettleConst;
use huolib\constant\WalletConst;
use huolib\status\CommonStatus;
use huolib\status\MemberStatus;
use huolib\status\SettleStatus;
use huolib\tool\StrUtils;

class MemWallet extends Base {
    /**
     * 更新渠道平台币
     *
     * @param  int  $mem_id
     * @param float $ptb_cnt
     * @param int   $type
     *
     * @return int
     */
    public function updatePtb($mem_id, $ptb_cnt, $type = SettleConst::SETTLE_WALLET_NO) {
        $_mc_class = MemCache::ins();
        $_me_data = $_mc_class->getMeInfoById($mem_id);
        if (empty($_me_data)) {
            return SettleStatus::REMAIN_NOT_ENOUGH;
        }
        $_total = $_me_data['ptb_total'];
        $_remain = $_me_data['ptb_cnt'];
        switch ($type) {
            case SettleConst::SETTLE_WALLET_DEDUCT:
                $_remain -= $ptb_cnt;
                break;
            case SettleConst::SETTLE_WALLET_ADD:
                $_remain += $ptb_cnt;
                $_total += $ptb_cnt;
                break;
            default:
        }
        if (StrUtils::compareNumber($_remain, 0) < 0) {
            return SettleStatus::REMAIN_NOT_ENOUGH;
        }
        $_me_data['ptb_total'] = $_total;
        $_me_data['ptb_cnt'] = $_remain;
        $_rs = $_mc_class->updateMeCache($mem_id, $_me_data);
        if (false == $_rs) {
            return SettleStatus::INNER_ERROR;
        } else {
            return SettleStatus::NO_ERROR;
        }
    }

    /**
     * 更新玩家游戏币
     *
     * @param int   $mem_id
     * @param int   $app_id
     * @param float $gm_cnt
     * @param int   $type
     *
     * @return int
     */
    public function updateGm($mem_id, $app_id, $gm_cnt, $type = SettleConst::SETTLE_WALLET_NO) {
        $_gmc_class = GmCache::ins();
        $_gm_data = $_gmc_class->getInfoByMemGame($mem_id, $app_id);
        if (empty($_gm_data)) {
            return SettleStatus::REMAIN_NOT_ENOUGH;
        }
        $_total = $_gm_data['total'];
        $_remain = $_gm_data['remain'];
        switch ($type) {
            case SettleConst::SETTLE_WALLET_DEDUCT:
                $_remain -= $gm_cnt;
                break;
            case SettleConst::SETTLE_WALLET_ADD:
                $_remain += $gm_cnt;
                $_total += $gm_cnt;
                break;
            default:
        }
        if (StrUtils::compareNumber($_remain, 0) < 0) {
            return SettleStatus::REMAIN_NOT_ENOUGH;
        }
        $_gm_data['total'] = $_total;
        $_gm_data['remain'] = $_remain;
        $_rs = $_gmc_class->updateGm($mem_id, $app_id, $_gm_data);
        if (false == $_rs) {
            return SettleStatus::INNER_ERROR;
        } else {
            return SettleStatus::NO_ERROR;
        }
    }

    /**
     * 玩家平台币充值订单
     *
     * @param WalletRequest $wr
     *
     * @return int
     */
    public function createPcOrder(WalletRequest $wr) {
        /* 更新玩家平台币 */
        if (OrderConst::PAY_STATUS_SUC == $wr->getStatus()) {
            $_rs = $this->updatePtb($wr->getMemId(), $wr->getPtbCnt(), SettleConst::SETTLE_WALLET_ADD);
            if (SettleStatus::NO_ERROR != $_rs) {
                return $_rs;
            }
        }
        /* 插入玩家平台币收入订单 */
        $_pc_data = $wr->getPtbChargeData();
        $_rs = (new PtbChargeModel())->createOrder($_pc_data);
        if (false == $_rs) {
            return SettleStatus::ORDER_CREATE_FAIL;
        }

        return SettleStatus::NO_ERROR;
    }

    /**
     * 玩家平台币消费订单
     *
     * @param WalletRequest $wr
     *
     * @return int
     */
    public function createPoOrder(WalletRequest $wr) {
        /* 更新玩家平台币 */
        if (OrderConst::PAY_STATUS_SUC == $wr->getStatus()) {
            /* 更新玩家平台币 */
            $_rs = $this->updatePtb($wr->getMemId(), $wr->getCostPtbCnt(), SettleConst::SETTLE_WALLET_DEDUCT);
            if (SettleStatus::NO_ERROR != $_rs) {
                return $_rs;
            }
        }
        /* 插入玩家平台币消费订单 */
        $_po_data = $wr->getPtbOrderData();
        $_po_data['status'] = OrderConst::PAY_STATUS_SUC;
        $_rs = (new PtbOrderModel())->createOrder($_po_data);
        if (false == $_rs) {
            return SettleStatus::ORDER_CREATE_FAIL;
        }

        return SettleStatus::NO_ERROR;
    }


    /**
     * 玩家游戏币充值订单
     *
     * @param WalletRequest $wr
     *
     * @return int
     */
    public function createGmcOrder(WalletRequest $wr) {
        /* 更新玩家游戏币 */
        if (OrderConst::PAY_STATUS_SUC == $wr->getStatus()) {
            /* 更新玩家游戏币 */
            $_rs = $this->updateGm($wr->getMemId(),$wr->getAppId(), $wr->getGmCnt(), SettleConst::SETTLE_WALLET_ADD);
            if (SettleStatus::NO_ERROR != $_rs) {
                return $_rs;
            }
        }
        /* 插入玩家游戏充值订单 */
        $_gmc_data = $wr->getGmChargeData();
        $_rs = (new GmChargeModel())->createOrder($_gmc_data);
        if (false == $_rs) {
            return SettleStatus::ORDER_CREATE_FAIL;
        }

        return SettleStatus::NO_ERROR;
    }

    /**
     * 玩家游戏币消费订单
     *
     * @param WalletRequest $wr
     *
     * @return int
     */
    public function createGmoOrder(WalletRequest $wr) {
        /* 更新玩家游戏币 */
        if (OrderConst::PAY_STATUS_SUC == $wr->getStatus()) {
            /* 更新玩家游戏币 */
            $_rs = $this->updateGm($wr->getMemId(), $wr->getAppId(), $wr->getCostGmCnt(), SettleConst::SETTLE_WALLET_DEDUCT);
            if (SettleStatus::NO_ERROR != $_rs) {
                return $_rs;
            }
        }
        /* 插入玩家平台币消费订单 */
        $_gmo_data = $wr->getGmOrderData();
        $_gmo_data['status'] = OrderConst::PAY_STATUS_SUC;
        $_rs = (new GmOrderModel())->createOrder($_gmo_data);
        if (false == $_rs) {
            return SettleStatus::ORDER_CREATE_FAIL;
        }

        return SettleStatus::NO_ERROR;
    }

    /**
     * 玩家平台币扣除
     *
     * @param WalletRequest $wr
     *
     * @return array|bool|int
     */
    private function createDeductOrder(WalletRequest $wr) {
        /* 更新玩家平台币 */
        if (OrderConst::PAY_STATUS_SUC == $wr->getStatus()) {
            /* 更新玩家平台币 */
            $_rs = $this->updatePtb($wr->getMemId(), $wr->getBackPtbCnt(), SettleConst::SETTLE_WALLET_DEDUCT);
            if (SettleStatus::NO_ERROR != $_rs) {
                return $_rs;
            }
        }
        /* 插入玩家平台币扣除订单 */
        $_deduct_data = $wr->getPtbPlayerDeductData();
        $_rs = (new PtbBackModel())->createOrder($_deduct_data);
        if (false == $_rs) {
            return SettleStatus::ORDER_CREATE_FAIL;
        }

        return SettleStatus::NO_ERROR;
    }

    /**
     * 玩家游戏币扣除
     *
     * @param WalletRequest $wr
     *
     * @return array|bool|int
     */
    private function createDeductGmOrder(WalletRequest $wr) {
        /* 更新玩家游戏币 */
        if (OrderConst::PAY_STATUS_SUC == $wr->getStatus()) {
            /* 更新玩家平台币 */
            $_rs = $this->updateGm($wr->getMemId(), $wr->getAppId(), $wr->getBackGmCnt(), SettleConst::SETTLE_WALLET_DEDUCT);
            if (SettleStatus::NO_ERROR != $_rs) {
                return $_rs;
            }
        }
        /* 插入玩家游戏币扣除订单 */
        $_deduct_data = $wr->getGmPlayerDeductData();
        $_rs = (new GmBackModel())->createOrder($_deduct_data);
        if (false == $_rs) {
            return SettleStatus::ORDER_CREATE_FAIL;
        }

        return SettleStatus::NO_ERROR;
    }

    /**
     * 官方给玩家发放平台币
     *
     * @param $mem_id
     * @param $ptb_cnt
     * @param $remark
     *
     * @return array
     */
    public function gainMemPtb($mem_id, $ptb_cnt, $remark) {
        $_mc_class = MemCache::ins();
        $_mem_data = $_mc_class->getInfoById($mem_id);
        $_me_data = $_mc_class->getMeInfoById($mem_id);
        if (empty($_mem_data) || empty($_me_data)) {
            $_code = MemberStatus::UID_INVALID;

            return $this->huoError($_code, MemberStatus::getMsg($_code));
        }
        $_wr_class = new WalletRequest();
        $_order_id = StrUtils::genOrderId(
            $_mem_data['agent_id'], $_mem_data['agent_id'], $mem_id, WalletConst::WALLET_ORDER_PREFIX_O2M
        );
        $_wr_class->setMemId($mem_id);
        $_wr_class->setOrderId($_order_id);
        $_wr_class->setType(WalletConst::WALLET_FROM_GIVE);
        $_wr_class->setPtbCnt($ptb_cnt);
        $_wr_class->setStatus(OrderConst::PAY_STATUS_SUC);
        $_wr_class->setRemark($remark);
        $_rs = $this->createPcOrder($_wr_class);
        if (SettleStatus::NO_ERROR != $_rs) {
            return $this->huoError($_rs, SettleStatus::getMsg($_rs));
        }
        $_code = CommonStatus::NO_ERROR;

        return $this->huoError($_code, CommonStatus::getMsg($_code));
    }

    /**
     * 官方从玩家账户中扣回平台币
     *
     * @param      $mem_id
     * @param      $order_ptb_cnt
     * @param      $ptb_cnt
     * @param      $remark
     * @param null $order_id
     *
     * @return array
     */
    public function deductMemPtb($mem_id, $order_ptb_cnt, $ptb_cnt, $remark, $order_id = null) {
        $_mc_class = MemCache::ins();
        $_mem_data = $_mc_class->getInfoById($mem_id);
        $_me_data = $_mc_class->getMeInfoById($mem_id);
        if (empty($_mem_data) || empty($_me_data)) {
            $_code = MemberStatus::UID_INVALID;

            return $this->huoError($_code, MemberStatus::getMsg($_code));
        }
        $_wr_class = new WalletRequest();
        $_wr_class->setMemId($mem_id);
        $_wr_class->setPtbCnt($order_ptb_cnt);
        $_wr_class->setBackPtbCnt($ptb_cnt);
        $_wr_class->setStatus(OrderConst::PAY_STATUS_SUC);
        $_wr_class->setRemark($remark);
        if (!is_null($order_id)) {
            $_wr_class->setOrderId($order_id);
        }
        $_rs = (new MemWallet())->createDeductOrder($_wr_class);
        if (SettleStatus::NO_ERROR != $_rs) {
            return $this->huoError($_rs, SettleStatus::getMsg($_rs));
        }
        $_code = CommonStatus::NO_ERROR;

        return $this->huoError($_code, CommonStatus::getMsg($_code));
    }

    /**
     * 官方给玩家发放游戏币
     *
     * @param $mem_id
     * @param $app_id
     * @param $gm_cnt
     * @param $remark
     *
     * @return array
     */
    public function gainMemGm($mem_id, $app_id, $gm_cnt, $remark) {
        $_mc_class = MemCache::ins();
        $_mem_data = $_mc_class->getInfoById($mem_id);

        $_gmc_class = GmCache::ins();
        $_gm_data = $_gmc_class->getInfoByMemGame($mem_id, $app_id);
        if (empty($_mem_data) || empty($_gm_data)) {
            $_code = MemberStatus::UID_INVALID;
            return $this->huoError($_code, MemberStatus::getMsg($_code));
        }

        $_wr_class = new WalletRequest();
        $_order_id = StrUtils::genOrderId(
            $_mem_data['agent_id'], $_mem_data['agent_id'], $mem_id, WalletConst::WALLET_ORDER_PREFIX_O2GM
        );
        $_wr_class->setMemId($mem_id);
        $_wr_class->setAppId($app_id);
        $_wr_class->setOrderId($_order_id);
        $_wr_class->setType(WalletConst::WALLET_FROM_GIVE);
        $_wr_class->setGmCnt($gm_cnt);
        $_wr_class->setStatus(OrderConst::PAY_STATUS_SUC);
        $_wr_class->setRemark($remark);
        $_rs = $this->createGmcOrder($_wr_class);
        if (SettleStatus::NO_ERROR != $_rs) {
            return $this->huoError($_rs, SettleStatus::getMsg($_rs));
        }
        $_code = CommonStatus::NO_ERROR;

        return $this->huoError($_code, CommonStatus::getMsg($_code));
    }

    /**
     * 官方从玩家账户中扣回游戏币
     *
     * @param      $mem_id
     * @param      $app_id
     * @param      $order_gm_cnt
     * @param      $gm_cnt
     * @param      $remark
     * @param null $order_id
     *
     * @return array
     */
    public function deductMemGm($mem_id, $app_id, $order_gm_cnt, $gm_cnt, $remark, $order_id = null) {
        $_mc_class = MemCache::ins();
        $_mem_data = $_mc_class->getInfoById($mem_id);

        $_gmc_class = GmCache::ins();
        $_gm_data = $_gmc_class->getInfoByMemGame($mem_id, $app_id);
        if (empty($_mem_data) || empty($_gm_data)) {
            $_code = MemberStatus::UID_INVALID;
            return $this->huoError($_code, MemberStatus::getMsg($_code));
        }

        $_wr_class = new WalletRequest();
        $_wr_class->setMemId($mem_id);
        $_wr_class->setAppId($app_id);
        $_wr_class->setGmCnt($order_gm_cnt);
        $_wr_class->setBackGmCnt($gm_cnt);
        $_wr_class->setStatus(OrderConst::PAY_STATUS_SUC);
        $_wr_class->setRemark($remark);
        if (!is_null($order_id)) {
            $_wr_class->setOrderId($order_id);
        }
        $_rs = (new MemWallet())->createDeductGmOrder($_wr_class);
        if (SettleStatus::NO_ERROR != $_rs) {
            return $this->huoError($_rs, SettleStatus::getMsg($_rs));
        }
        $_code = CommonStatus::NO_ERROR;

        return $this->huoError($_code, CommonStatus::getMsg($_code));
    }
}