/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: ShoppingCart
 * @Package cn.freemud.controller
 * @Description:
 * @author: ping.wu
 * @date: 2018/5/18 18:07
 * @version V1.0
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
package cn.freemud.controller;

import cn.freemud.annotations.IsConvertEN;
import cn.freemud.annotations.LogIgnore;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.demo.controller.ShoppingCartDemoController;
import cn.freemud.entities.dto.GetMemberInfoRequestDto;
import cn.freemud.entities.vo.*;
import cn.freemud.entities.vo.coupon.CouponAvailableRequestVo;
import cn.freemud.enums.CouponTypeEnum;
import cn.freemud.enums.OrderChannelType;
import cn.freemud.enums.ResponseResult;
import cn.freemud.service.OpenStoreIappWxappConfigService;
import cn.freemud.service.ShoppingCartNewService;
import cn.freemud.service.impl.ShoppingCartMallServiceImpl;
import cn.freemud.service.impl.ShoppingCartMealServiceImpl;
import cn.freemud.service.impl.ShoppingCartNewServiceImpl;
import cn.freemud.service.impl.ShoppingCartToolsServiceImpl;
import cn.freemud.utils.ResponseUtil;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.enums.IappIdType;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.base.SDKCommonBaseContextWare;
import com.freemud.application.sdk.api.log.ApiAnnotation;
import com.freemud.application.sdk.api.log.LogParams;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import io.swagger.annotations.Api;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(value = "/shoppingCart", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Api(value = "购物车 controller", tags = {"购物车管理接口"})
public class ShoppingCartController {

    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;

    @Autowired
    private OpenStoreIappWxappConfigService openStoreIappWxappConfigService;


    @Autowired
    private ShoppingCartDemoController shoppingCartDemoController;

    @Resource
    private MapperFacade mapperFacade;

    /**
     * 从微信卡券向购物车中添加商品
     */
    @PostMapping(value = "/addGoodsByCard")
    @LogIgnore(logMessage = "addGoodsByCard")
    public BaseResponse addGoodsByCard(@Validated @LogParams @RequestBody AddGoodsByWeixinCardRequestVo request) {
        return getInstanceByRequest(request).addGoodsByCard(request);
    }

    /**
     * 向购物车中添加商品
     */
    @IsConvertEN
    @PostMapping(value = "/addGoods")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "addGoods")
    public BaseResponse addGoods(@Validated @LogParams @RequestBody AddShoppingCartGoodsRequestVo request) {
        ShoppingCartNewService instanceByRequest = getInstanceByRequest(request);
        if (instanceByRequest instanceof ShoppingCartNewServiceImpl && SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).newShoppingCartGray(request.getPartnerId(), request.getShopId())){
            Map requestMap = mapperFacade.map(request, Map.class);
            return shoppingCartDemoController.addGoods(requestMap);
        } else {
            return instanceByRequest.addGoods(request);
        }
    }

    /**
     * 修改购物车中商品数量
     */
    @IsConvertEN
    @PostMapping(value = "/updateGoodsQty")
    @LogIgnore(logMessage = "updateGoodsQty")
    public BaseResponse updateGoodsQty(@Validated @LogParams @RequestBody UpdateShoppingCartGoodsQtyRequestVo request) {
        ShoppingCartNewService instanceByRequest = getInstanceByRequest(request);
        if (instanceByRequest instanceof ShoppingCartNewServiceImpl && SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).newShoppingCartGray(request.getPartnerId(), request.getShopId())){
            Map requestMap = mapperFacade.map(request, Map.class);
            return shoppingCartDemoController.updateGoodsQty(requestMap);
        } else {
            return instanceByRequest.updateGoodsQty(request);
        }
    }

    /**
     * 查询购物车信息
     */
    @IsConvertEN
    @PostMapping(value = "/listCartGoods")
    @LogIgnore(logMessage = "listCartGoods")
    public BaseResponse listCartGoods(@Validated @LogParams @RequestBody ShoppingCartInfoRequestVo request) {
        // 代金券 & 折扣券互斥校验
        BaseResponse baseResponse = verifyCouponCodes(request.getCouponCodes());
        if (baseResponse !=null) {
            return baseResponse;
        }
        ShoppingCartNewService instanceByRequest = getInstanceByRequest(request);
        if (instanceByRequest instanceof ShoppingCartNewServiceImpl && SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).newShoppingCartGray(request.getPartnerId(), request.getShopId())){
            Map requestMap = mapperFacade.map(request, Map.class);
            return shoppingCartDemoController.listCartGoods(requestMap);
        } else {
            return instanceByRequest.getGoodsList(request);
        }
    }

    /**
     * 查询购车信息无配送费
     * SVC卡支付check，check购物车金额加配送费小于储值卡金额
     */
    @PostMapping(value = "/listCartGoodsCheck")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "listCartGoodsCheck")
    public BaseResponse listCartGoodsCheck(@Validated @LogParams @RequestBody ShoppingCartInfoRequestVo request) {
        // 代金券 & 折扣券互斥校验
        BaseResponse baseResponse = verifyCouponCodes(request.getCouponCodes());
        if (baseResponse !=null) {
            return baseResponse;
        }
        return getInstanceByRequest(request).getGoodsListCheck(request);
    }

//    /**
//     * 清空购物车
//     */
//    @PostMapping(value = "/clear")
//    public BaseResponse clear(@Validated @RequestBody ShoppingCartClearRequestVo request) {
//        return shoppingCartService.clear(request);
//    }

    /**
     * 清空购物车
     */
    @IsConvertEN
    @PostMapping(value = "/clearCartGoods")
    @LogIgnore(logMessage = "clearCartGoods")
    public BaseResponse clearCartGoods(@Validated @LogParams @RequestBody ShoppingCartClearRequestVo request) {
        String sessionId = request.getSessionId();
        if (StringUtils.isEmpty(sessionId)) {
            String tableNumber = request.getTableNumber();
            if (StringUtils.isEmpty(tableNumber)) {
                return ResponseUtil.error(ResponseResult.PARAMETER_MISSING, "sessionId和tableNumber不能同时为空");
            }
            return getInstanceByIAppId(IappIdType.WC_XCX.getCode()).clear(request);
        }
        return getInstanceByRequest(request).clear(request);
    }

    /**
     * 获取购物车均摊详情，点 "去支付" 时调用
     *
     * @param getShoppingCartGoodsApportionRequestVo
     * @return
     */
    @IsConvertEN
    @PostMapping(value = "/getShoppingCartGoodsApportion")
    @LogIgnore(logMessage = "getShoppingCartGoodsApportion")
    public BaseResponse getShoppingCartGoodsApportion(@Validated @LogParams @RequestBody GetShoppingCartGoodsApportionRequestVo getShoppingCartGoodsApportionRequestVo) {
        if (getShoppingCartGoodsApportionRequestVo == null || getShoppingCartGoodsApportionRequestVo.getShoppingCartInfoRequestVo() == null) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
        }
        ShoppingCartInfoRequestVo shoppingCartInfoRequestVo = getShoppingCartGoodsApportionRequestVo.getShoppingCartInfoRequestVo();

        ShoppingCartNewService instanceByRequest = getInstanceByRequest(shoppingCartInfoRequestVo);
        if (instanceByRequest instanceof ShoppingCartNewServiceImpl && SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).newShoppingCartGray(shoppingCartInfoRequestVo.getPartnerId(), shoppingCartInfoRequestVo.getShopId())){
            return shoppingCartDemoController.getShoppingCartGoodsApportion(getShoppingCartGoodsApportionRequestVo);
        } else {
            return instanceByRequest.getShoppingCartGoods(shoppingCartInfoRequestVo, getShoppingCartGoodsApportionRequestVo.getPremiumExchangeActivity());
        }
    }


    private ShoppingCartNewService getInstanceByRequest(BaseRequestVo requestVo) {
        if (requestVo.getChannelType() != null && OrderChannelType.SAASMALL.getCode().equals(requestVo.getChannelType())) {
            return SDKCommonBaseContextWare.getBean(ShoppingCartMallServiceImpl.class);
        } else {
            return getInstanceBySessionId(requestVo.getSessionId());
        }
    }

    private ShoppingCartNewService getInstanceBySessionId(String sessionId) {

        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(sessionId);
        if (assortmentCustomerInfoVo == null || StringUtils.isBlank(assortmentCustomerInfoVo.getIappId())) {
            return getInstanceByIAppId(IappIdType.IBZ_DC_XCX.getCode());
        }
        String iAppId = assortmentCustomerInfoVo.getIappId();
        return getInstanceByIAppId(iAppId);
    }

    private ShoppingCartNewService getInstanceByIAppId(String iAppId) {
        if (IappIdType.WC_XCX.getCode().equals(iAppId)) {
            //围餐
            return SDKCommonBaseContextWare.getBean(ShoppingCartMealServiceImpl.class);
        }
        return SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class);
    }

    /**
     * 清空购物车{技术支持用}
     */
    @ApiAnnotation(logMessage = "clear/goods")
    @PostMapping(value = "/clearGoods")
    public BaseResponse clearGoods(@Validated @LogParams @RequestBody ShoppingCartClearToolsRequestVo request) {
        return SDKCommonBaseContextWare.getBean(ShoppingCartToolsServiceImpl.class).clear(request);
    }


    /**
     * 线下订单查询接口
     */
    @PostMapping(value = "/getMemberInfo")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "/getMemberInfo")
    public BaseResponse getMemberInfo(@LogParams @RequestBody GetMemberInfoRequestDto request) {
        return SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).getMemberInfo(request);
    }

    /**
     * 结算页获取是否展示订单那备注配置
     */
    @PostMapping(value = "/getOpenStoreIappWxappConfig")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "/getOpenStoreIappWxappConfig")
    public BaseResponse getOpenStoreIappWxappConfig(@LogParams @RequestBody OpenStoreIappWxappConfigRequestVo request) {
        return openStoreIappWxappConfigService.getOpenStoreIappWxappConfig(request);
    }

    /**
     * 结算页获取加价购活动商品列表
     */
    @PostMapping(value = "/premiumExchange")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "/premiumExchange")
    public BaseResponse premiumExchange(@LogParams @RequestBody @Validated PremiumExchangeRequestVo request) {
        return SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).premiumExchange(request);
    }
    /**
     * 券码查询购物车商品信息(平台结算页可用券列表用)
     */
    @PostMapping(value = "/getCartInfoByUser")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "/getCartInfoByUser")
    public BaseResponse getCartInfoByUser(@LogParams @RequestBody @Validated CouponAvailableRequestVo request) {
        return SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).getCartInfoByUser(request);
    }

    /**
     * 【C端服务端】批量一键加购
     * 替换老门店的商品到切换的门店下
     */
    @PostMapping(value = "/replaceGoodsByShop")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "/replaceGoodsByShop")
    public BaseResponse replaceGoodsByShop(@LogParams @RequestBody @Validated ShopGoodsReplaceVo request) {
        return SDKCommonBaseContextWare.getBean(ShoppingCartNewServiceImpl.class).replaceGoodsByShop(request);
    }


    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartService;
    @Autowired
    private AssortmentCustomerInfoManager assortmentCustomerInfoManager;
    /**
     * 测试用，后续删除
     */
    @PostMapping(value = "/test/putCache")
    @LogIgnore(excludeStatusCodes = {ResponseCodeConstant.RESPONSE_SUCCESS_STR},logMessage = "/putCache")
    public BaseResponse putCache(@LogParams @RequestBody @Validated PutCacheVo request) {

        com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto cartParamDto = new com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto();
        cartParamDto.setPartnerId(request.getPartnerId());
        cartParamDto.setStoreId(request.getStoreId());
        cartParamDto.setBuyType(0);
        cartParamDto.setCartGoodsList(request.getCartGoodsList());
        for (String sessionId : request.getSessionIds()){
            AssortmentCustomerInfoVo assortmentCustomerInfoVo = assortmentCustomerInfoManager.getCustomerInfoByObject(sessionId);
            cartParamDto.setUserId(assortmentCustomerInfoVo.getMemberId());
            shoppingCartService.setCartGoodsListTest(cartParamDto, LogThreadLocal.getTrackingNo(),10, TimeUnit.MINUTES);
        }
        return new BaseResponse("1","100","");
    }

    /**
     *  校验 代金券/ 折扣券互斥
     * @param couponCodes
     * @return
     */
    private BaseResponse  verifyCouponCodes (List<ShoppingCartInfoRequestVo.couponCode> couponCodes){
        if (CollectionUtils.isNotEmpty(couponCodes) && couponCodes.size() > 1) {
            long count = couponCodes.stream().filter(c -> c.getCouponType().compareTo(CouponTypeEnum.TYPE_1.getCode()) == 0
                    || c.getCouponType().compareTo(CouponTypeEnum.TYPE_3.getCode()) == 0).count();
            if (count > 2) {
                return ResponseUtil.error(ResponseResult.SHOPPING_CART_COUPON_MUTUAL_EXCLUSION);
            }
        }
        return null;
    }
}
