<?php
/**
 * 计算优惠类
 */
namespace JinDouYun\Model\Cart;

use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\StatusCode;

use JinDouYun\Model\Market\MUserCoupon;
use JinDouYun\Model\Market\MVipCard;

class MPreferentialProcess{
    private $onlineUserCenterid;
    private $onlineEnterPriseId;
    private $userCouponIsMutex; // 用户领取过优惠劵是否互斥

    public function __construct($onlineUserCenterid, $onlineEnterPriseId)
    {
        $this->onlineUserCenterid = $onlineUserCenterid;
        $this->onlineEnterPriseId = $onlineEnterPriseId;
    }

    /**
     * 计算优惠核心方法
     * @param array $cartGoodsData  购物车商品数据
     * @param int   $vipCardId      要使用的会员卡id
     * @params int  $userCouponId   要使用的优惠劵id
     */
    public function Preferential($cartGoodsData, $vipCardId, $userCouponId)
    {
        $tmpCartGoodsData = $cartGoodsData;

        // 未指定要使用的会员卡id或优惠劵id
        if( !$vipCardId && !$userCouponId ) {
            return ResultWrapper::success($cartGoodsData);
        }

        $vipCartData = [];
        // 处理vip会员卡主流程
        if( $vipCardId ){
            // 获取vip会员卡信息
            $vipCartData = self::vipCartData($vipCardId);
            if(!$vipCartData->isSuccess()){
                return ResultWrapper::fail($vipCartData->getData(), $vipCartData->getErrorCode());
            }
            $vipCartData = $vipCartData->getData();

            // 没有折扣的会员卡不计算折扣
            if($vipCartData['vipDiscount'] == StatusCode::$delete){
                return ResultWrapper::success($cartGoodsData);
            }

            // 计算vip会员卡折后金额
            $cartGoodsData = self::vipCartCompute($cartGoodsData, $vipCartData);
            if(!$cartGoodsData->isSuccess()){
                return ResultWrapper::fail($cartGoodsData->getData(), $cartGoodsData->getErrorCode());
            }
            $cartGoodsData = $cartGoodsData->getData();
        }

        // 处理优惠券主流程
        if( $userCouponId ){
            // 获取优惠劵信息
            $userCouponData = self::couponData($userCouponId);
            if(!$userCouponData->isSuccess()){
                return ResultWrapper::fail($userCouponData->getData(), $userCouponData->getErrorCode());
            }
            $userCouponData = $userCouponData->getData();
            $this->userCouponIsMutex = $userCouponData['isMutex']; // 优惠劵与其他活动互斥
            /*if ($this->userCouponIsMutex == StatusCode::$standard){
                return ResultWrapper::success($cartGoodsData);
            }*/
            // 判断会员卡是否有优惠,且vip折扣后实付金额 小于 优惠金额，则先优惠后折扣
            if(  $cartGoodsData['vipDiscount'] > 0 && ($cartGoodsData['payMoney'] < $userCouponData['reducePrice']) ) {
                // 计算优惠劵优惠后金额
                $tmpCartGoodsData = self::userCouponCompute($tmpCartGoodsData, $userCouponData);
                if(!$tmpCartGoodsData->isSuccess()){
                    return ResultWrapper::fail($tmpCartGoodsData->getData(), $tmpCartGoodsData->getErrorCode());
                }
                $tmpCartGoodsData = $tmpCartGoodsData->getData();

                // 计算vip会员卡折后金额
                $tmpCartGoodsData = self::vipCartCompute($tmpCartGoodsData, $vipCartData);
                if(!$tmpCartGoodsData->isSuccess()){
                    return ResultWrapper::fail($tmpCartGoodsData->getData(), $tmpCartGoodsData->getErrorCode());
                }
                $cartGoodsData = $tmpCartGoodsData->getData();

            }else{
                // 计算优惠劵优惠后金额
                $cartGoodsData = self::userCouponCompute($cartGoodsData, $userCouponData);
                if(!$cartGoodsData->isSuccess()){
                    return ResultWrapper::fail($cartGoodsData->getData(), $cartGoodsData->getErrorCode());
                }
                $cartGoodsData = $cartGoodsData->getData();
            }
        }
        return ResultWrapper::success($cartGoodsData);
    }



    /**
     * 优惠劵计算流程
     * @params $vipCardId  int  会员卡id
     * @return ResultWrapper
     */
    public function userCouponCompute($cartGoodsData, $userCouponData)
    {

        switch ($userCouponData['applyRange']){
            case StatusCode::$applyRange['allGoods']: // 全部商品
                // 判断是否满足优惠券使用门槛
                if( $userCouponData['minPrice'] == 0 || $cartGoodsData['payMoney'] >= $userCouponData['minPrice'] ){
                    $result = self::userCouponDiscountCommon($cartGoodsData['payMoney'], $userCouponData['reducePrice']);
                    $cartGoodsData['payMoney']     = $result['discountEndPayMoney']; // 修改订单总实际支付金额
                    $cartGoodsData['preferential'] = $result['discountIngPayMoney']; // 修改订单优惠劵总优惠金额
                }
                break;
            case StatusCode::$applyRange['appointCategory']: // 指定分类
                $result = self::userCouponDiscountByGoods('categoryId', 'categoryCollect', $cartGoodsData,$userCouponData);
                if(!$result->isSuccess()){
                    return ResultWrapper::fail($result->getErrorCode(), $result->getData());
                }
                $cartGoodsData = $result->getData();
                break;
            case StatusCode::$applyRange['appointBrand']: // 指定品牌
                $result = self::userCouponDiscountByGoods('brandId', 'brandCollect', $cartGoodsData,$userCouponData);
                if(!$result->isSuccess()){
                    return ResultWrapper::fail($result->getErrorCode(), $result->getData());
                }
                $cartGoodsData = $result->getData();
                break;
            case StatusCode::$applyRange['goodsCollect']: // 指定商品
                $result = self::userCouponDiscountByGoods('goodsId', 'goodsCollect', $cartGoodsData, $userCouponData);
                if(!$result->isSuccess()){
                    return ResultWrapper::fail($result->getErrorCode(), $result->getData());
                }
                $cartGoodsData = $result->getData();
                break;
        }

        if ($cartGoodsData['payMoney'] < 0) {
            $cartGoodsData['payMoney'] = 0;  // 如果折后金额小于0，统一归零处理
        }
        return ResultWrapper::success($cartGoodsData);
    }

    /**
     * 指定商品分类/商品品牌/商品 计算优惠统一方法
     * @params string $typeField 指定类型
     * @params string $typeField 类型对应字段名
     */
    public function userCouponDiscountByGoods($type, $typeField, $cartGoodsData, $userCouponData)
    {
        if( empty($userCouponData[$typeField]) ){
            return ResultWrapper::success($cartGoodsData);
        }

        $goodsAmount = 0; // 满足优惠劵指定分类下的商品总金额
        $couponBrand = explode(',', $userCouponData[$typeField]);
        // 累加订单中每个店铺下参与优惠劵的商品总金额
        foreach ($cartGoodsData['goodsData'] as $shop) {
            foreach ($shop['shopGoodsData'] as $value) {
                if (in_array($value[$type], $couponBrand)) {
                    $goodsAmount = bcadd($goodsAmount, $value['totalMoney']);
                }
            }
        }

        if( $goodsAmount <= 0 ){
            return ResultWrapper::fail('参与优惠劵优惠的商品总金额异常', ErrorCode::$notAllowAccess);
        }

        // 判断是否满足优惠券使用门槛
        if( $userCouponData['minPrice'] == 0 || $goodsAmount >= $userCouponData['minPrice'] ){
            $result = self::userCouponDiscountCommon($goodsAmount, $userCouponData['reducePrice']);
            $cartGoodsData['payMoney']     = bcsub($cartGoodsData['payMoney'],  $result['discountIngPayMoney'], 2); // 修改订单总实际支付金额
            $cartGoodsData['preferential'] = $result['discountIngPayMoney']; // 修改订单优惠劵总优惠金额
        }

        return ResultWrapper::success($cartGoodsData);
    }

    /**
     * 优惠劵优惠统一方法
     * @params float $discountBeforePayMoney 优惠劵优惠前金额
     * @params float $discountMoney  优惠劵优惠金额
     * @return array 优惠后金额
     */
    public function userCouponDiscountCommon($discountBeforePayMoney, $discountMoney)
    {
        $discountEndPayMoney = bcsub($discountBeforePayMoney, $discountMoney, 2);
        // 如果优惠后的金额小于0，说明优惠金额大于商品原价了，优惠金额 = 商品金额, 多余优惠浪费掉了
        $discountIngPayMoney = ($discountEndPayMoney < 0 ) ? $discountBeforePayMoney : $discountMoney;

        return [
            'discountEndPayMoney' => ($discountEndPayMoney < 0) ? 0 : $discountEndPayMoney,
            'discountIngPayMoney' => $discountIngPayMoney,
        ];
    }



    /**
     * vip会员卡优惠计算流程
     * @params $vipCardId  int  会员卡id
     * @return ResultWrapper
     */
    public function vipCartCompute($cartGoodsData, $vipCartData)
    {
        $discount = bcdiv($vipCartData['discount'], 10, 2);  //折扣率

        // 所有商品
        if ($vipCartData['mode'] == StatusCode::$standard) {
            $result = self::vipCartDiscountCommon($cartGoodsData['payMoney'], $discount);
            $cartGoodsData['payMoney']     = $result['discountEndPayMoney']; // 修改订单总实际支付金额
            $cartGoodsData['vipDiscount']  = $result['discountIngPayMoney']; // 修改订单总会员卡优惠金额

            //是否开启折上折 暂时不支持 代码需要测试
            /*if ($cardInfo['doubleDiscount'] == StatusCode::$standard) {
                $data['vipDoubleDiscount'] = bcsub($data['payMoney'], bcmul($data['payMoney'], $discount, 2), 2);//折上折优惠金额
                $data['payMoney'] = bcmul($data['payMoney'], $discount, 2);
                if ($data['payMoney'] < 0) {
                    $data['payMoney'] = 0;//若优惠券后价格小于0(可能是由于优惠券设计不合理)
                }
            }*/
        }else{ // 部分商品
            if( empty($vipCartData['goodsIds']) ){
                return ResultWrapper::success($cartGoodsData);
            }

            $goodsAmount = 0; // 参与会员卡折扣的商品总金额
            $vipGoodsIds = explode(',', $vipCartData['goodsIds']);  // 会员卡设置的参与折扣商品
            // 累加订单中每个店铺下参与会员卡折扣的商品总金额
            foreach ($cartGoodsData['goodsData'] as $shop) {
                foreach ($shop['shopGoodsData'] as $value) {
                    if (in_array($value['goodsId'], $vipGoodsIds)) {
                        $goodsAmount = bcadd($goodsAmount, $value['totalMoney']);
                    }
                }
            }

            if( $goodsAmount <= 0 ){
                return ResultWrapper::fail('参与会员卡优惠的商品总金额异常', ErrorCode::$notAllowAccess);
            }

            $result = self::vipCartDiscountCommon($goodsAmount, $discount);
            $cartGoodsData['payMoney']     = bcsub($cartGoodsData['payMoney'], $result['discountIngPayMoney']);  // 修改订单总实际支付金额
            $cartGoodsData['vipDiscount']  = $result['discountIngPayMoney']; // 修改订单总会员卡优惠金额

            //是否开启折上折 暂时不支持 代码需要测试
            /*if ($cardInfo['doubleDiscount'] == StatusCode::$standard) {
                $data['vipDoubleDiscount'] = bcsub($data['payMoney'], bcmul($data['payMoney'], $discount, 2), 2);//折上折优惠金额
                $data['payMoney'] = bcmul($data['payMoney'], $discount, 2);
                if ($data['payMoney'] < 0) {
                    $data['payMoney'] = 0;//若优惠券后价格小于0(可能是由于优惠券设计不合理)
                }
            }*/
        }

        if ($cartGoodsData['payMoney'] < 0) {
            $cartGoodsData['payMoney'] = 0;  // 如果折后金额小于0，统一归零处理
        }
        return ResultWrapper::success($cartGoodsData);
    }

    /**
     * 计算会员卡折扣统一方法
     * @params float $discountBeforePayMoney 会员卡优惠前金额
     * @params float $discount  会员卡折扣率
     * @return array 优惠后金额
     */
    public function vipCartDiscountCommon($discountBeforePayMoney, $discount)
    {
        $discountEndPayMoney = bcmul( $discountBeforePayMoney, $discount, 2); // vip会员卡打折以后的订单金额 0.19
        $discountIngPayMoney = bcsub($discountBeforePayMoney, $discountEndPayMoney, 2); // vip会员卡打折免掉的金额 18.81

        return [
            'discountEndPayMoney' => ($discountEndPayMoney < 0) ? 0 : $discountEndPayMoney,
            'discountIngPayMoney' => ($discountIngPayMoney < 0) ? 0 : $discountIngPayMoney,
        ];
    }


    /**
     * 获取vip会员卡信息
     * @params $vipCardId  int  会员卡id
     * @return ResultWrapper
     */
    public function vipCartData($vipCardId)
    {
        $objMVipCard = new MVipCard($this->onlineEnterPriseId, $this->onlineUserCenterid, true);
        $dbResult = $objMVipCard->getVipCardInfo($vipCardId);
        if(!$dbResult->isSuccess()){
            return ResultWrapper::fail($dbResult->getData(), $dbResult->getErrorCode());
        }
        $vipCartData = $dbResult->getData();
        if( empty($vipCardId) ){
            return ResultWrapper::fail('要使用的会员卡不存在', ErrorCode::$contentNotExists);
        }

        // 判断是否删除
        if($vipCartData['deleteStatus'] == StatusCode::$delete){
            return ResultWrapper::fail('当前购买的vip会员卡被删除了', ErrorCode::$notAllowAccess);
        }

        // 判断是否禁用
        if($vipCartData['enableStatus'] == StatusCode::$delete){
            return ResultWrapper::fail('当前购买的vip会员卡被禁用了', ErrorCode::$notAllowAccess);
        }

        return ResultWrapper::success($vipCartData);
    }

    /**
     * 获取优惠劵信息
     * @params $userCouponId  int  用户领取优惠劵id
     * @return ResultWrapper
     */
    public function couponData($userCouponId)
    {
        // 查询用户领取过的优惠劵数据
        $objMUserCoupon = new MUserCoupon($this->onlineUserCenterid, $this->onlineEnterPriseId);
        $condition = [
            'id' => $userCouponId,
        ];
        $userCouponData = $objMUserCoupon->getUserCoupon($condition);
        if(!$userCouponData->isSuccess()){
            return ResultWrapper::fail($userCouponData->getData(), $userCouponData->getErrorCode());
        }
        $userCouponData = $userCouponData->getData();
        if(empty($userCouponData)){
            return ResultWrapper::fail('要使用的优惠劵不存在', ErrorCode::$contentNotExists);
        }
        $userCouponData = array_pop($userCouponData);

        // 判断是否使用过了
        if($userCouponData['isUse'] == StatusCode::$delete){
            return ResultWrapper::fail('当前领取的优惠券已经使用过了', ErrorCode::$notAllowAccess);
        }

        // 判断下有效期
        if (time() <= $userCouponData['startTime'] || time() >= $userCouponData['endTime']){
            return ResultWrapper::fail('当前领取的优惠券已经过期了', ErrorCode::$notAllowAccess);
        }
        return ResultWrapper::success($userCouponData);
    }
}
