package com.xxfc.platform.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.github.wxiaoqi.security.admin.entity.AppUserLogin;
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.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.util.OrderUtil;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.activity.feign.ActivityFeign;
import com.xxfc.platform.order.biz.BaseOrderBiz;
import com.xxfc.platform.order.biz.OrderItemBiz;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.contant.enumerate.OrderTypeEnum;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.entity.inter.OrderDetail;
import com.xxfc.platform.order.mqhandler.RabbitProduct;
import com.xxfc.platform.order.pojo.price.OrderPriceVO;
import com.xxfc.platform.universal.entity.Dictionary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Transactional
public abstract class AbstractOrderHandle<Biz extends BaseBiz, Detail extends OrderDetail> implements UserRestInterface {

    public static final int VERSION_INITIAL = 0;

    @Autowired
    protected Biz detailBiz;

    protected Map<String, Dictionary> dictionaryMap;

    @Autowired
    RabbitProduct rabbitProduct;

    @Autowired
    protected BaseOrderBiz baseOrderBiz;

    @Autowired
    protected OrderItemBiz orderItemBiz;

    @Autowired
    ActivityFeign activityFeign;

    @Autowired
    protected UserFeign userFeign;

    @Override
    public UserFeign getUserFeign() {
        return userFeign;
    }

    protected OrderTypeEnum orderTypeEnum;

    protected Integer channel;

    /**
     * 创建基础订单
     * @return
     */
    public BaseOrder createBaseOrder(Integer orderOrigin, String facilitatePhone, AppUserDTO appUserDTO, String orderNo) {
        BaseOrder baseOrder = new BaseOrder();

        //设置下单来源
        baseOrder.setOrderOrigin(orderOrigin);

        //根据facilitatePhone 查询后台管理系统人员 未完成
        if(StrUtil.isNotBlank(facilitatePhone)) {
            baseOrder.setFacilitatePhone(facilitatePhone);
            List<AppUserLogin> appUserDTOList = userFeign.getOne(facilitatePhone, null);
            if(null != appUserDTOList && appUserDTOList.size() > 0) {
                baseOrder.setFacilitateId(appUserDTOList.get(0).getId());
            }
        }

        //设置订单号
        if(StrUtil.isNotBlank(orderNo)) {
            baseOrder.setNo(orderNo);
        } else {
            baseOrder.setNo(OrderUtil.GetOrderNumber("", OrderUtil.APP_MID));
        }
        //设置订单类型
        if(null == orderTypeEnum)
            throw new BaseException(ResultCode.NOTEXIST_CODE);
        else {
            baseOrder.setType(orderTypeEnum.getCode());
        }
        //设置订单状态
        baseOrder.setStatus(OrderStatusEnum.ORDER_CRT.getCode());

        //设置初始版本号
        baseOrder.setVersion(VERSION_INITIAL);

        //设置用户id
        baseOrder.setUserId(appUserDTO.getUserid());
        baseOrder.setMemberLevel(appUserDTO.getMemberLevel());

        //设置上级
        baseOrder.setParentUserId(appUserDTO.getParentId());
        baseOrder.setParentUserCompanyId(appUserDTO.getParentCompanyId());
        baseOrder.setParentPositionId(appUserDTO.getParentPositionTempId());

        return baseOrder;
    }

    /**
     * 创建基础订单
     * @return
     */
    public BaseOrder createBaseOrder(Integer orderOrigin, String facilitatePhone, AppUserDTO appUserDTO) {
        return createBaseOrder(orderOrigin, facilitatePhone, appUserDTO, null);
    }

    public void initDetail(Detail detail) {
//        Integer appUserId = (null == detail.getAppUserDTO())? Integer.valueOf(BaseContextHandler.getUserID()): detail.getAppUserDTO().getUserid();
        BaseOrder order = createBaseOrder(detail.getOrderOrigin(), detail.getFacilitatePhone(), detail.getAppUserDTO());
        detail.setOrder(order);
    }

    /**
     * 创建订单及其子项
     * @param detail
     */
    public void createOrder(Detail detail) {
        //初始化
        initDetail(detail);
        //计算价格
        handleCalculate(detail);
        //插入baseOrder
        baseOrderBiz.insertSelective(detail.getOrder());
        //处理detail
        handleDetail(detail);
    }

    /**
     * 处理订单详情
     * @param detail
     */
    public void handleDetail(Detail detail){
        detail.setOrderId(detail.getOrder().getId());
        detailBiz.insertSelective(detail);
        detail.getOrder().setDetailId(detail.getId());
//        int updateResult =baseOrderBiz.updateSelectiveByIdRe(detail.getOrder());
//        if(updateResult > 0) {
//            detail.getOrder().setVersion(detail.getOrder().getVersion() + 1);
//        }
        detail.setOrder(baseOrderBiz.updateSelectiveByIdReT(detail.getOrder()));

        //插入item
        if(null != detail.getItems() && detail.getItems().size() > 0) {
            orderItemBiz.insertMultiSelective(detail.getItems().stream().map(v -> {
                v.setOrderId(detail.getOrderId());
                return v;
            }).collect(Collectors.toList()));
        }

        //判断是否价格为0
        BigDecimal realAmount = detail.getOrder().getRealAmount();
        if(BigDecimal.ZERO.compareTo(realAmount) > 0) {
            throw new BaseException(ResultCode.FAILED_CODE);
        }else if(BigDecimal.ZERO.compareTo(realAmount) == 0) {
            //直接支付 0表示不需要支付
            baseOrderBiz.payNotifyHandle(detail.getOrder().getNo(), null, detail.getOrderOrigin(), 0);
        }
    }
    /**
     * 计算价格
     * @param detail
     */
    public OrderPriceVO calculatePrice(Detail detail) {
        OrderPriceVO priceVO = new OrderPriceVO();
        priceVO.setGoodsAmount(BigDecimal.ZERO);
        priceVO.setOrderAmount(BigDecimal.ZERO);
        priceVO.setRealAmount(BigDecimal.ZERO);
        return priceVO;
    }

    /**
     * 计算价格
     * @param detail
     */
    public void handleCalculate(Detail detail) {
        OrderPriceVO opv = calculatePrice(detail);
        BeanUtil.copyProperties(opv, detail.getOrder());
        BeanUtil.copyProperties(opv, detail);
    }

}
