package com.xxfc.platform.order.service;

import cn.hutool.core.bean.BeanUtil;
import com.github.wxiaoqi.security.admin.entity.BaseUserMemberLevel;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.auth.client.config.UserAuthConfig;
import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.activity.feign.ActivityFeign;
import com.xxfc.platform.order.biz.OrderCostDetailBiz;
import com.xxfc.platform.order.biz.OrderMemberDetailBiz;
import com.xxfc.platform.order.biz.OrderTemplateBiz;
import com.xxfc.platform.order.contant.enumerate.ItemTypeEnum;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.contant.enumerate.OrderTypeEnum;
import com.xxfc.platform.order.entity.OrderItem;
import com.xxfc.platform.order.pojo.order.MemberBO;
import com.xxfc.platform.order.pojo.price.OrderPriceVO;
import com.xxfc.platform.tour.feign.TourFeign;
import com.xxfc.platform.universal.constant.DictionaryKey;
import com.xxfc.platform.universal.feign.ThirdFeign;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.stream.Collectors;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;
import static com.xxfc.platform.universal.constant.DictionaryKey.APP_ORDER;

@Service
@Log4j
public class OrderMemberService extends AbstractOrderHandle<OrderMemberDetailBiz, MemberBO> implements UserRestInterface {

    @Autowired
    TourFeign tourFeign;

    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    ThirdFeign thirdFeign;


    private static Integer IS_CHILD = 1;
    private static Integer LEVEL_DEFAULT = 0;
    private static Integer NUMBER_ZERO = 0;
    private static Long autoCancelTime;

    @Autowired
    OrderCostDetailBiz orderCostDetailBiz;

    @Autowired
    OrderTemplateBiz orderTemplateBiz;

    @Autowired
    protected UserAuthConfig userAuthConfig;

    @Autowired
    ActivityFeign activityFeign;

    @Autowired
    public HttpServletRequest request;

    @PostConstruct
    public void init(){
        this.orderTypeEnum = OrderTypeEnum.MEMBER;
    }

    @Override
    public void initDetail(MemberBO bo) {
        super.initDetail(bo);
        initDictionary();
        BaseUserMemberLevel buml = userFeign.level(bo.getMemberLevel());
        if(!bo.getMemberLevelId().equals(buml.getId())) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE, new HashSet<String>(){{
                add("MemberLevelId 和 MemberLevel不对称");
            }});
        }
        bo.setBaseUserMemberLevel(buml);
        bo.setRentFreeNum(buml.getNumber());
        bo.setRebate(buml.getDiscount());
    }

    public void initDictionary() {
        dictionaryMap = thirdFeign.dictionaryGetAll4Map().getData();
        this.autoCancelTime = Long.valueOf(dictionaryMap.get(APP_ORDER+ "_"+ DictionaryKey.ACT_MEMBER).getDetail());
    }

    @Override
    public void handleDetail(MemberBO bo) {
        //设置订单状态为3
        bo.getOrder().setStatus(OrderStatusEnum.ORDER_UNPAY.getCode());
        //设置订单图片
        bo.getOrder().setPicture(bo.getBaseUserMemberLevel().getItemImg());
        //设置订单名称
        bo.getOrder().setName(bo.getBaseUserMemberLevel().getName());

        OrderItem memberItem = bo.getItemByTypeEnum(ItemTypeEnum.MEMBER);
        BigDecimal amount = memberItem.getTotalAmount();

        //如果有使用优惠券，则扣减
        if(BigDecimal.ZERO.compareTo(bo.getOrder().getCouponAmount()) < 0) {
            activityFeign.use(bo.getOrder().getUserId(), bo.getTickerNo(), bo.getOrder().getNo(), channel, amount, ActivityFeign.TYPE_USE);
        }

        super.handleDetail(bo);

        //发送定时取消订单(30分钟)
        rabbitProduct.sendDelayMessage(bo.getOrder(), autoCancelTime);
    }

    @Override
    public void handleCalculate(MemberBO bo) {
        OrderPriceVO tpv = calculatePrice(bo);
        BeanUtil.copyProperties(tpv, bo.getOrder());
        BeanUtil.copyProperties(tpv, bo);
    }

    @Override
    public OrderPriceVO calculatePrice(MemberBO detail) {
        BigDecimal orderAmount = BigDecimal.ZERO;
        BigDecimal goodsAmount = BigDecimal.ZERO;
        BigDecimal realAmount = BigDecimal.ZERO;
        BigDecimal couponAmount = BigDecimal.ZERO;

        //设置Item
        OrderItem memberOrderItem = orderItemBiz.initOrderItem(detail.getBaseUserMemberLevel().getPrice(), 1, detail.getBaseUserMemberLevel().getName(), detail.getBaseUserMemberLevel().getId(), ItemTypeEnum.MEMBER);

        detail.setItems(new ArrayList<OrderItem>());
        detail.getItems().add(memberOrderItem);

        //商品价格
        goodsAmount = goodsAmount.add(memberOrderItem.getCalculateAmount(Boolean.TRUE));

        //vehicleAmount 优惠券处理
        if(null != detail.getTickerNo() && detail.getTickerNo().size() > 0) {
            couponAmount = activityFeign.use(detail.getOrder().getUserId(), detail.getTickerNo(), detail.getOrder().getNo(), channel, goodsAmount, ActivityFeign.TYPE_NO_USE);
            if(couponAmount.compareTo(BigDecimal.ZERO) > 0) {
                detail.getOrder().setCouponTickerNos(detail.getTickerNo().stream().collect(Collectors.joining(",")));
                detail.getOrder().setHasDiscount(SYS_TRUE);
                memberOrderItem.handleCouponAmount(couponAmount);
            }
        }

            //订单总价格
        orderAmount = orderAmount.add(goodsAmount);
            //真实价格
        realAmount = realAmount.add(orderAmount).subtract(couponAmount);

            //生成订单明细
        OrderPriceVO opv = new OrderPriceVO();
        opv.setOrderAmount(orderAmount);
        opv.setGoodsAmount(goodsAmount);
        opv.setRealAmount(realAmount);
        opv.setCouponAmount(couponAmount);

        return opv;
    }
}
