package cn.iocoder.yudao.module.order.api;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.boot.module.order.api.OrderApi;
import cn.iocoder.boot.module.order.api.dto.*;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.customer.dal.dataobject.customer.CustomerDO;
import cn.iocoder.yudao.module.customer.service.customer.CustomerService;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderConsignee.OrderConsigneeDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderConsignor.OrderConsignorDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderItem.OrderItemDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderObjective.OrderObjectiveDO;
import cn.iocoder.yudao.module.order.service.order.*;
import cn.iocoder.yudao.module.order.service.order.impl.OrderItemServiceImpl;
import cn.iocoder.yudao.module.order.service.orderOperateLog.OrderOperateLogService;
import cn.iocoder.yudao.module.order.vo.orderOperateLog.OrderOperateLogCreateReqVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Joiner;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.ORDER_IS_APPROVAL_IN_PROCESS_WITH_ORDERNOS;

@Service
@Validated
public class OrderApiImpl implements OrderApi {
    @Resource
    private OrderService orderService;
    @Resource
    private OrderBusinessService orderBusinessService;
    @Resource
    private CustomerService customerService;
    @Resource
    private OrderObjectiveService objectiveService;
    @Resource
    private OrderConsigneeService orderConsigneeService;
    @Resource
    private OrderItemServiceImpl orderItemService;
    @Resource
    private OrderConsignorService orderConsignorService;
    @Resource
    private OrderOperateLogService orderOperateLogService;

    @Override
    public OrderRespDTO getOrder(Long id, String orderNo) {
        OrderDO orderDO;
        if (id != null) {
            orderDO = orderService.getById(id);
        } else {
            orderDO = orderService.selectOne(new LambdaQueryWrapper<OrderDO>().eq(OrderDO::getOrderNo, orderNo).last("limit 1"));
        }
        if (orderDO == null) {
            return null;
        }
        OrderRespDTO orderRespDTO = new OrderRespDTO();
        BeanUtils.copyProperties(orderDO, orderRespDTO);

        // 设置目的地信息
        OrderObjectiveDO orderObjectiveDO = objectiveService.getByOrderId(orderDO.getOrderId());
        if (orderObjectiveDO != null) {
            OrderObjectiveApiDO orderObjectiveApiDO = new OrderObjectiveApiDO();
            BeanUtils.copyProperties(orderObjectiveDO, orderObjectiveApiDO);
            orderRespDTO.setOrderObjectiveDO(orderObjectiveApiDO);
        }
        // 设置发货人信息
        OrderConsignorDO orderConsignorDO =
                orderConsignorService.getOne(new LambdaQueryWrapper<OrderConsignorDO>().eq(OrderConsignorDO::getOrderId, orderDO.getOrderId()).orderByDesc(OrderConsignorDO::getId).last("limit 1"));
        if (Objects.nonNull(orderConsignorDO)) {
            OrderConsignorApiDO orderConsignorApiDO = new OrderConsignorApiDO();
            BeanUtils.copyProperties(orderConsignorDO, orderConsignorApiDO);
            orderRespDTO.setOrderConsignorDO(orderConsignorApiDO);
        }
        // 设置收货人信息
        OrderConsigneeDO orderConsigneeByOrderId = orderConsigneeService.getOrderConsigneeByOrderId(orderDO.getOrderId());
        if (orderConsigneeByOrderId != null) {
            OrderConsigneeApiDO orderConsigneeApiDO = new OrderConsigneeApiDO();
            BeanUtils.copyProperties(orderConsigneeByOrderId, orderConsigneeApiDO);
            orderRespDTO.setOrderConsigneeDO(orderConsigneeApiDO);
        }

        return orderRespDTO;
    }

    @Override
    public boolean isFirstOrder(Long customerId) {
        // 只要发过货或者收过货都不算首单
        return orderConsignorService.selectCount("customer_id", customerId) <= 1 && orderConsigneeService.selectCount("customer_id", customerId) <= 1;
    }

    @Override
    public List<OrderItemRespDTO> getOrderItemsByOrderId(Long orderId) {
        List<OrderItemDO> orderItemDOS = orderItemService.selectList("order_id", orderId);
        if (CollectionUtil.isNotEmpty(orderItemDOS)) {
            return orderItemDOS.stream().map(orderItemDO -> new OrderItemRespDTO(orderItemDO.getChargeWeight(), orderItemDO.getChargeVolume())).collect(Collectors.toList());
        }
        return null;
    }

    @Override
    public void createOrderOperateLog(OrderOperateLogDTO orderOperateLogDTO) {
        OrderOperateLogCreateReqVO createReqVO = new OrderOperateLogCreateReqVO();
        BeanUtils.copyProperties(orderOperateLogDTO, createReqVO);
        orderOperateLogService.createOrderAsyncOperateLog(createReqVO);
    }

    @Override
    public boolean mergeOrder(Long customerIdSaved, Long customerIdDeleted) {

        CustomerDO customerDeleted = customerService.getById(customerIdDeleted);
        CustomerDO customerSaved = customerService.getById(customerIdSaved);

        // 将customerId=customerIdDeleted的订单的customerId更新为customerIdSaved
        List<OrderDO> list = orderService.selectList(new LambdaQueryWrapperX<OrderDO>().eq(OrderDO::getCustomerId, customerIdDeleted));
        if (CollectionUtil.isNotEmpty(list)) {

            // 订单有审核中，则不允许合并
            List<String> auditingOrderNoList = list.stream().filter(t -> t.getAuditType() != 0).map(OrderDO::getOrderNo).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(auditingOrderNoList)) {
                throw exception(ORDER_IS_APPROVAL_IN_PROCESS_WITH_ORDERNOS, Joiner.on(",").join(auditingOrderNoList));
            }

            for (OrderDO order : list) {
                order.setCustomerId(customerIdSaved);
                order.setUpdateTime(new Date());
                orderService.updateById(order);

                // 保存操作日志
                orderBusinessService.addOrderOperateLog(order.getOrderId(), "合并客户-归属人",
                        String.format("将此订单的客户由【%d-%s-%s】合并为【%d-%s-%s】", customerDeleted.getId(), customerDeleted.getNumber(), customerDeleted.getName(),
                                customerSaved.getId(), customerSaved.getNumber(), customerSaved.getName()));
            }
        }

        // 修改收货人
        List<OrderConsigneeDO> orderConsigneeDOList = orderConsigneeService.selectList(new LambdaQueryWrapperX<OrderConsigneeDO>().eq(OrderConsigneeDO::getCustomerId, customerIdDeleted));
        if (CollectionUtil.isNotEmpty(orderConsigneeDOList)) {
            for (OrderConsigneeDO orderConsigneeDO : orderConsigneeDOList) {
                orderConsigneeDO.setCustomerId(customerIdSaved);
                orderConsigneeDO.setCustomerNumber(customerSaved.getNumber());
                orderConsigneeService.updateById(orderConsigneeDO);

                // 保存操作日志
                orderBusinessService.addOrderOperateLog(orderConsigneeDO.getOrderId(), "合并客户-收货人",
                        String.format("将此订单的收货人客户由【%d-%s-%s】合并为【%d-%s-%s】", customerDeleted.getId(), customerDeleted.getNumber(), customerDeleted.getName(),
                                customerSaved.getId(), customerSaved.getNumber(), customerSaved.getName()));
            }
        }

        // 修改发货人
        List<OrderConsignorDO> orderConsignorDOList = orderConsignorService.selectList(new LambdaQueryWrapperX<OrderConsignorDO>().eq(OrderConsignorDO::getCustomerId, customerIdDeleted));
        if (CollectionUtil.isNotEmpty(orderConsignorDOList)) {
            for (OrderConsignorDO orderConsignorDO : orderConsignorDOList) {
                orderConsignorDO.setCustomerId(customerIdSaved);
                orderConsignorDO.setCustomerNumber(customerSaved.getNumber());
                orderConsignorService.updateById(orderConsignorDO);

                // 保存操作日志
                orderBusinessService.addOrderOperateLog(orderConsignorDO.getOrderId(), "合并客户-发货人",
                        String.format("将此订单的发货人客户由【%d-%s-%s】合并为【%d-%s-%s】", customerDeleted.getId(), customerDeleted.getNumber(), customerDeleted.getName(),
                                customerSaved.getId(), customerSaved.getNumber(), customerSaved.getName()));
            }
        }

        return false;
    }
}
