package co.yixiang.yshop.module.order.service.storeorder;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.constant.ShopConstants;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
import co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.module.express.dal.dataobject.electronicsorder.ElectronicsOrderDO;
import co.yixiang.yshop.module.express.dal.dataobject.express.ExpressDO;
import co.yixiang.yshop.module.express.dal.mysql.electronicsorder.ElectronicsOrderMapper;
import co.yixiang.yshop.module.express.dal.redis.express.ExpressRedisDAO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiBaseDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoElectronicsOrderDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoElectronicsOrderGoodsDTO;
import co.yixiang.yshop.module.express.kdniao.model.vo.KdniaoOrderVO;
import co.yixiang.yshop.module.express.kdniao.util.KdniaoUtil;
import co.yixiang.yshop.module.express.service.electronicsorder.ElectronicsOrderService;
import co.yixiang.yshop.module.express.service.express.ExpressService;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserRespVO;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.dal.mysql.user.MemberUserMapper;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.message.enums.WechatTempateEnum;
import co.yixiang.yshop.module.message.mq.producer.WeixinNoticeProducer;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.*;
import co.yixiang.yshop.module.order.controller.admin.storeorderelectronics.vo.StoreOrderElectronicsCreateReqVO;
import co.yixiang.yshop.module.order.convert.storeorder.StoreOrderConvert;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo.StoreOrderCartInfoDO;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.order.enums.AppFromEnum;
import co.yixiang.yshop.module.order.enums.OrderLogEnum;
import co.yixiang.yshop.module.order.enums.UpdateOrderEnum;
import co.yixiang.yshop.module.order.service.storeorderelectronics.StoreOrderElectronicsService;
import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusService;
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_ORDER_NOT_EXISTS;

/**
 * 订单 Service 实现类
 *
 * @author yshop
 */
@Slf4j
@Service
@Validated
public class StoreOrderServiceImpl implements StoreOrderService {

    @Resource
    private StoreOrderMapper storeOrderMapper;
    @Resource
    private MemberUserMapper memberUserMapper;
    @Resource
    private StoreOrderCartInfoMapper storeOrderCartInfoMapper;
    @Resource
    private StoreOrderStatusService storeOrderStatusService;
    @Resource
    private AppStoreOrderService appStoreOrderService;
    @Resource
    private ElectronicsOrderService electronicsOrderService;
    @Resource
    private ExpressService expressService;
    @Resource
    private ExpressRedisDAO expressRedisDAO;
    @Resource
    private StoreOrderElectronicsService storeOrderElectronicsService;
    @Resource
    private MemberUserService userService;
    @Resource
    private WeixinNoticeProducer weixinNoticeProducer;
    @Resource
    private RedissonClient redissonClient;

    @Override
    public Long createStoreOrder(StoreOrderCreateReqVO createReqVO) {
        // 插入
        StoreOrderDO storeOrder = StoreOrderConvert.INSTANCE.convert(createReqVO);
        storeOrderMapper.insert(storeOrder);
        // 返回
        return storeOrder.getId();
    }

    @Override
    public void updateStoreOrder(StoreOrderUpdateReqVO updateReqVO) {
        // 校验存在
        validateStoreOrderExists(updateReqVO.getId());
        // 更新
        StoreOrderDO updateObj = StoreOrderConvert.INSTANCE.convert(updateReqVO);
        //发货
        if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())){
            updateObj.setStatus(OrderInfoEnum.STATUS_1.getValue());
        }
        storeOrderMapper.updateById(updateObj);

        if(UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())){
            //增加状态
            storeOrderStatusService.create(updateObj.getUid(),updateObj.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                    "已发货 快递公司：" + updateObj.getDeliveryName() + "快递单号：" + updateObj.getDeliveryId());

            MemberUserDO userInfo = userService.getUser(updateObj.getUid());
            //发送消息队列进行推送消息
            if(userInfo.getLoginType().equals(AppFromEnum.ROUNTINE.getValue())){
                weixinNoticeProducer.sendNoticeMessage(updateObj.getUid(), WechatTempateEnum.DELIVERY_SUCCESS.getValue(),
                        WechatTempateEnum.SUBSCRIBE.getValue(),updateObj.getOrderId(),
                        updateObj.getPayPrice().toString(),"",updateObj.getDeliveryName(),
                        updateObj.getDeliveryId());
            }else if(userInfo.getLoginType().equals(AppFromEnum.WECHAT.getValue())){
                weixinNoticeProducer.sendNoticeMessage(updateObj.getUid(),WechatTempateEnum.PAY_SUCCESS.getValue(),
                        WechatTempateEnum.TEMPLATES.getValue(),updateObj.getOrderId(),
                        updateObj.getPayPrice().toString(),"",updateObj.getDeliveryName(),
                        updateObj.getDeliveryId());
            }

            //延时队列 七天自动收货
            try {
                RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(ShopConstants.REDIS_ORDER_OUTTIME_UNCONFIRM);
                RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
                delayedQueue.offer(updateReqVO.getOrderId(), ShopConstants.ORDER_OUTTIME_UNCONFIRM, TimeUnit.DAYS);
                String s = TimeUnit.SECONDS.toSeconds(ShopConstants.ORDER_OUTTIME_UNCONFIRM) + "天";
                log.info("添加延时队列成功 ，延迟时间：" + s);
            } catch (Exception e) {
                log.error(e.getMessage());
            }

        }

    }

    @Override
    public void deleteStoreOrder(Long id) {
        // 校验存在
        validateStoreOrderExists(id);
        // 删除
        StoreOrderDO storeOrderDO = StoreOrderDO.builder()
                .isSystemDel(ShopCommonEnum.DELETE_1.getValue())
                .id(id)
                .build();
        storeOrderMapper.updateById(storeOrderDO);
    }

    @Override
    public void payStoreOrder(Long id) {
        // 校验存在
        validateStoreOrderExists(id);
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        storeOrderDO.setPaid(OrderInfoEnum.PAY_STATUS_1.getValue());
        storeOrderDO.setPayTime(LocalDateTime.now());
        storeOrderMapper.updateById(storeOrderDO);

        //增加状态
        storeOrderStatusService.create(storeOrderDO.getUid(),storeOrderDO.getId(), OrderLogEnum.OFFLINE_PAY.getValue(),
                OrderLogEnum.OFFLINE_PAY.getDesc());
    }

    @Override
    public void takeStoreOrder(Long id) {
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        appStoreOrderService.takeOrder(storeOrderDO.getOrderId(),storeOrderDO.getUid());
    }


    private void validateStoreOrderExists(Long id) {
        if (storeOrderMapper.selectById(id) == null) {
            throw exception(STORE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public StoreOrderRespVO getStoreOrder(Long id) {
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        StoreOrderRespVO storeOrderRespVO = StoreOrderConvert.INSTANCE.convert(storeOrderDO);
        MemberUserDO memberUserDO = memberUserMapper.selectById(storeOrderRespVO.getUid());
        UserRespVO  userRespVO = UserConvert.INSTANCE.convert4(memberUserDO);
        storeOrderRespVO.setUserRespVO(userRespVO);
        storeOrderRespVO.setStatusStr(this.handleOrderStatus(storeOrderRespVO.getPaid()
                ,storeOrderRespVO.getStatus(),storeOrderRespVO.getRefundStatus(),storeOrderRespVO.getIsSystemDel()));
        return storeOrderRespVO;
    }

    @Override
    public List<StoreOrderDO> getStoreOrderList(Collection<Long> ids) {
        return storeOrderMapper.selectBatchIds(ids);
    }

    /**
     * 订单查询
     * @param pageReqVO 分页查询
     * @return
     */
    @Override
    public PageResult<StoreOrderRespVO> getStoreOrderPage(StoreOrderPageReqVO pageReqVO) {
        PageResult<StoreOrderDO> pageResult =  storeOrderMapper.selectPage(pageReqVO);
        PageResult<StoreOrderRespVO> storeOrderRespVO =  StoreOrderConvert.INSTANCE.convertPage(pageResult);
        for (StoreOrderRespVO storeOrderRespVO1 : storeOrderRespVO.getList()) {
            LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreOrderCartInfoDO::getOid,storeOrderRespVO1.getId());
            List<StoreOrderCartInfoDO> storeOrderCartInfoDOList = storeOrderCartInfoMapper.selectList(wrapper);
            MemberUserDO memberUserDO = memberUserMapper.selectById(storeOrderRespVO1.getUid());
            UserRespVO  userRespVO = UserConvert.INSTANCE.convert4(memberUserDO);
            storeOrderRespVO1.setStoreOrderCartInfoDOList(storeOrderCartInfoDOList);
            storeOrderRespVO1.setUserRespVO(userRespVO);
            storeOrderRespVO1.setStatusStr(this.handleOrderStatus(storeOrderRespVO1.getPaid()
                    ,storeOrderRespVO1.getStatus(),storeOrderRespVO1.getRefundStatus(),storeOrderRespVO1.getIsSystemDel()));
        }
        return storeOrderRespVO;
    }

    @Override
    public List<StoreOrderDO> getStoreOrderList(StoreOrderExportReqVO exportReqVO) {
        return storeOrderMapper.selectList(exportReqVO);
    }

    @Override
    public String printOrder(Long id, Long electId) {
        KdniaoElectronicsOrderDTO queryDTO = new KdniaoElectronicsOrderDTO();
        List<KdniaoElectronicsOrderGoodsDTO> kdniaoElectronicsOrderGoodsDTOList = new ArrayList<>();

        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreOrderCartInfoDO::getOid,storeOrderDO.getId());
        List<StoreOrderCartInfoDO> storeOrderCartInfoDOList = storeOrderCartInfoMapper.selectList(wrapper);
        //组合请求参数
        ElectronicsOrderDO electronicsOrderDO = electronicsOrderService.getElectronicsOrder(electId);
        queryDTO.setMemberID(storeOrderDO.getUid());
        queryDTO.setOrderCode(storeOrderDO.getOrderId());

        ExpressDO expressDO = expressService.getExpress(electronicsOrderDO.getShipperId());
        queryDTO.setShipperCode(expressDO.getCode());
        queryDTO.setCustomerName(electronicsOrderDO.getCustomerName());
        queryDTO.setCustomerPwd(electronicsOrderDO.getCustomerPwd());
        queryDTO.setSendSite(electronicsOrderDO.getSendSite());
        queryDTO.setPaytype(electronicsOrderDO.getPaytype());
        queryDTO.setMonthCode(electronicsOrderDO.getMonthCode());
        queryDTO.setIsReturnSignBill(electronicsOrderDO.getIsReturnSignBill());
        queryDTO.setOperateRequire(electronicsOrderDO.getOperateRequire());
        queryDTO.setExpType(electronicsOrderDO.getExpType());
        queryDTO.setCost(storeOrderDO.getPayPostage().doubleValue());
        queryDTO.setCompany(electronicsOrderDO.getCompany());
        queryDTO.setName(electronicsOrderDO.getName());
        queryDTO.setTel(electronicsOrderDO.getTel());
        queryDTO.setMobile(electronicsOrderDO.getMobile());
        queryDTO.setPostCode(electronicsOrderDO.getPostCode());
        queryDTO.setProvinceName(electronicsOrderDO.getProvinceName());
        queryDTO.setCityName(electronicsOrderDO.getCityName());
        queryDTO.setExpAreaName(electronicsOrderDO.getExpAreaName());
        queryDTO.setAddress(electronicsOrderDO.getAddress());
        queryDTO.setReceiverCompany("yshop");
        queryDTO.setReceiverName(storeOrderDO.getRealName());
        queryDTO.setReceiverTel(storeOrderDO.getUserPhone());
        List<String> stringList = StrUtil.split(storeOrderDO.getUserAddress()," ");
        if(stringList.size() >= 4) {
            queryDTO.setReceiverProvinceName(stringList.get(0));
            queryDTO.setReceiverCityName(stringList.get(1));
            queryDTO.setReceiverExpAreaName(stringList.get(2));
            queryDTO.setReceiverAddress(stringList.get(3));
        }
        queryDTO.setIsNotice(electronicsOrderDO.getIsNotice());
        queryDTO.setStartDate(electronicsOrderDO.getStartDate());
        queryDTO.setEndDate(electronicsOrderDO.getEndDate());
        queryDTO.setIsReturnTemp(electronicsOrderDO.getIsReturnTemp());
        queryDTO.setRemark(electronicsOrderDO.getRemark());

        int quantity = 0;
        BigDecimal weight = BigDecimal.ZERO;

        for (StoreOrderCartInfoDO storeOrderCartInfoDO : storeOrderCartInfoDOList) {
            KdniaoElectronicsOrderGoodsDTO electronicsOrderGoodsDTO = new KdniaoElectronicsOrderGoodsDTO();
            AppStoreCartQueryVo cartQueryVo = JSON.parseObject(storeOrderCartInfoDO.getCartInfo(),
                    AppStoreCartQueryVo.class);
            electronicsOrderGoodsDTO.setGoodsName(cartQueryVo.getProductInfo().getStoreName());
            electronicsOrderGoodsDTO.setGoodsCode(cartQueryVo.getProductInfo().getId().toString());
            electronicsOrderGoodsDTO.setGoodsQuantity(cartQueryVo.getCartNum());
            electronicsOrderGoodsDTO.setGoodsPrice(cartQueryVo.getTruePrice().doubleValue());
            electronicsOrderGoodsDTO.setGoodsWeight(cartQueryVo.getProductInfo().getAttrInfo().getWeight().doubleValue());
            electronicsOrderGoodsDTO.setGoodsDesc(cartQueryVo.getProductInfo().getDescription());

            kdniaoElectronicsOrderGoodsDTOList.add(electronicsOrderGoodsDTO);

            quantity = quantity + cartQueryVo.getCartNum();
            weight  = NumberUtil.add(weight, cartQueryVo.getProductInfo().getAttrInfo().getWeight());
        }
        queryDTO.setQuantity(quantity);
        queryDTO.setWeight(weight.doubleValue());

        KdniaoApiBaseDTO kdniaoApiBaseDTO = expressRedisDAO.get();
        queryDTO.setEBusinessID(kdniaoApiBaseDTO.getEBusinessID());
        queryDTO.setApiKey(kdniaoApiBaseDTO.getApiKey());

        //订单打印
        KdniaoOrderVO kdniaoOrderVO = KdniaoUtil.getOrderInfo(queryDTO,kdniaoElectronicsOrderGoodsDTOList);

        //订单单号回填
        storeOrderDO.setDeliveryId(kdniaoOrderVO.getOrder().getLogisticCode());
        storeOrderDO.setDeliveryName(expressDO.getName());
        storeOrderDO.setDeliverySn(kdniaoOrderVO.getOrder().getShipperCode());
        storeOrderDO.setStatus(OrderInfoEnum.STATUS_1.getValue());
        storeOrderMapper.updateById(storeOrderDO);

        //增加状态
        storeOrderStatusService.create(storeOrderDO.getUid(),storeOrderDO.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                "已发货 快递公司：" + storeOrderDO.getDeliveryName() + "快递单号：" + storeOrderDO.getDeliveryId());

        //插入记录电子面单订单记录
        StoreOrderElectronicsCreateReqVO createReqVO = new  StoreOrderElectronicsCreateReqVO();
        createReqVO.setOrderSn(storeOrderDO.getOrderId());
        createReqVO.setCustomerName(electronicsOrderDO.getCustomerName());
        createReqVO.setCustomerPwd(electronicsOrderDO.getCustomerPwd());
        createReqVO.setPrintTemplate(kdniaoOrderVO.getPrintTemplate());
        createReqVO.setLogisticCode(kdniaoOrderVO.getOrder().getLogisticCode());
        createReqVO.setShipperCode(kdniaoOrderVO.getOrder().getShipperCode());
        createReqVO.setOrder(JSON.toJSONString(kdniaoOrderVO.getOrder()));
        storeOrderElectronicsService.createStoreOrderElectronics(createReqVO);

        return kdniaoOrderVO.getPrintTemplate();
    }

    /**
     * 处理订单状态
     * @param payStatus
     * @param status
     * @param refundStatus
     * @param del
     * @return
     */
    private String handleOrderStatus(Integer payStatus,Integer status,Integer refundStatus,Integer del) {
        String statusName = "";
        if (del == 1){
            statusName = "已删除";
        }else if (payStatus == 0 && status == 0) {
            statusName = "未支付";
        } else if (payStatus == 1 && status == 0 && refundStatus == 0) {
            statusName = "未发货";
        }  else if (payStatus == 1 && status == 1 && refundStatus == 0) {
            statusName = "待收货";
        }  else if (payStatus == 1 && status == 2 && refundStatus == 0) {
            statusName = "待评价";
        } else if (payStatus == 1 && status == 3 && refundStatus == 0) {
            statusName = "已完成";
        } else if (payStatus == 1 && refundStatus == 2) {
            statusName = "已退款";
        }
        else if (payStatus == 1 && refundStatus == 1) {
            statusName = "退款中";
        }
        return statusName;
    }

}
