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

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.customer.dal.dataobject.customer.CustomerDO;
import cn.iocoder.yudao.module.customer.service.customer.CustomerService;
import cn.iocoder.yudao.module.depository.dal.dataobject.warehouse.WarehouseLineDO;
import cn.iocoder.yudao.module.depository.dal.mysql.warehouse.WarehouseLineMapper;
import cn.iocoder.yudao.module.ecw.dal.dataobject.unit.UnitDO;
import cn.iocoder.yudao.module.ecw.service.unit.UnitService;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderItem.OrderItemDO;
import cn.iocoder.yudao.module.order.service.order.OrderItemService;
import cn.iocoder.yudao.module.order.service.order.OrderQueryService;
import cn.iocoder.yudao.module.order.service.order.OrderService;
import cn.iocoder.yudao.module.order.vo.order.WarehouseInInfoVO;
import cn.iocoder.yudao.module.wealth.dal.dataobject.commissionPayable.CommissionPayableDO;
import cn.iocoder.yudao.module.wealth.dal.dataobject.receivable.ReceivableDO;
import cn.iocoder.yudao.module.wealth.service.commissionPayable.CommissionPayableService;
import cn.iocoder.yudao.module.wealth.service.receivable.ReceivableService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


@Component
@TenantJob
@Slf4j
public class OrderCommissionPayableJob implements JobHandler {
    @Resource
    private OrderService orderService;
    @Resource
    private UnitService unitService;

    @Resource
    private WarehouseLineMapper warehouseLineMapper;
    @Resource
    private OrderItemService orderItemService;

    @Resource
    private ReceivableService receivableService;

    @Resource
    private CommissionPayableService commissionPayableService;
    @Resource
    private OrderQueryService orderQueryService;
    @Resource
    private CustomerService customerService;

    @Override
    public String execute(String param) throws Exception {
        // 获取已提货的有佣金订单
        List<OrderDO> orderDOList = orderQueryService.commissionOrderList();
        if (CollectionUtil.isNotEmpty(orderDOList)) {
            log.info("开始生成佣金应付...");
            int num = 0;
            for (OrderDO orderDO : orderDOList) {
                // 获取订单应付是否全部核销
                List<ReceivableDO> receivableDOList = receivableService.list(new LambdaQueryWrapper<ReceivableDO>().eq(ReceivableDO::getOrderId, orderDO.getOrderId()));
                if (CollectionUtil.isNotEmpty(receivableDOList)) {
                    long count = receivableDOList.stream().filter(receivable -> receivable.getState() != 2).count();
                    if (count == 0) {
                        // 订单应收全部核销,
                        List<OrderItemDO> orderItemDOList = orderItemService.list(new LambdaQueryWrapper<OrderItemDO>()
                                .eq(OrderItemDO::getOrderId, orderDO.getOrderId())
                                .in(OrderItemDO::getCommissionType, 1, 2, 3));
                        for (OrderItemDO orderItemDO : orderItemDOList) {
                            WarehouseInInfoVO warehouseInInfoVO = orderItemDO.getWarehouseInInfoVO();
                            if (Objects.isNull(warehouseInInfoVO) || warehouseInInfoVO.getCartonsNum() == 0){
                                // 未入仓订单项不生成佣金
                                continue;
                            }
                            List<CommissionPayableDO> list = commissionPayableService.list(new LambdaQueryWrapper<CommissionPayableDO>().eq(CommissionPayableDO::getOrderItemId, orderItemDO.getOrderItemId()));
                            if (CollectionUtil.isNotEmpty(list)) {
                                // 有应付
                                CommissionPayableDO plainCommissionPayable = list.stream().filter(p -> p.getFeeType() == 1).findFirst().orElse(null);
                                if (Objects.isNull(plainCommissionPayable)) {
                                    // 新增明佣
                                    plainCommissionPayable = new CommissionPayableDO();
                                }
                                if (orderItemDO.getPlainCommission().compareTo(BigDecimal.ZERO) > 0) {
                                    // 更新明佣
                                    addCommissionPayable(plainCommissionPayable, orderItemDO, orderDO, 1, orderItemDO.getPlainCommission());
                                } else {
                                    if (Objects.nonNull(plainCommissionPayable.getId())) {
                                        plainCommissionPayable.setDeleted(Boolean.TRUE);
                                        commissionPayableService.updateById(plainCommissionPayable);
                                    }
                                }
                                CommissionPayableDO hiddenCommissionPayable = list.stream().filter(p -> p.getFeeType() == 2).findFirst().orElse(null);
                                if (Objects.isNull(hiddenCommissionPayable)) {
                                    // 新增明佣
                                    hiddenCommissionPayable = new CommissionPayableDO();
                                }
                                if (orderItemDO.getHiddenCommission().compareTo(BigDecimal.ZERO) > 0) {
                                    // 更新暗佣
                                    addCommissionPayable(hiddenCommissionPayable, orderItemDO, orderDO, 2, orderItemDO.getHiddenCommission());
                                } else {
                                    if (Objects.nonNull(hiddenCommissionPayable.getId())) {
                                        hiddenCommissionPayable.setDeleted(Boolean.TRUE);
                                        commissionPayableService.updateById(hiddenCommissionPayable);
                                    }
                                }
                            } else {
                                CommissionPayableDO plainCommissionPayable = new CommissionPayableDO();
                                if (orderItemDO.getPlainCommission().compareTo(BigDecimal.ZERO) > 0) {
                                    // 更新明佣
                                    addCommissionPayable(plainCommissionPayable, orderItemDO, orderDO, 1, orderItemDO.getPlainCommission());
                                }
                                CommissionPayableDO hiddenCommissionPayable = new CommissionPayableDO();
                                if (orderItemDO.getHiddenCommission().compareTo(BigDecimal.ZERO) > 0) {
                                    // 更新暗佣
                                    addCommissionPayable(hiddenCommissionPayable, orderItemDO, orderDO, 2, orderItemDO.getHiddenCommission());
                                }
                            }
                        }
                        num++;
                        orderService.update(new LambdaUpdateWrapper<OrderDO>().set(OrderDO::getCommissionPayable, Boolean.TRUE).eq(OrderDO::getOrderId, orderDO.getOrderId()));
                    }
                }

            }
            log.info("生成佣金应付结束...共产生{}单应付", num);
        }
        return "";
    }

    private void addCommissionPayable(CommissionPayableDO commissionPayable,
                                      OrderItemDO orderItemDO,
                                      OrderDO orderDO,
                                      Integer feeType,
                                      BigDecimal amount) {
        commissionPayable.setOrderId(orderItemDO.getOrderId());
        commissionPayable.setOrderNo(orderItemDO.getOrderNo());
        commissionPayable.setPayableNo(orderDO.getContainerNumber());
        commissionPayable.setOrderItemId(orderItemDO.getOrderItemId());
        commissionPayable.setFeeType(feeType);
        commissionPayable.setUnitPrice(amount);
        commissionPayable.setTitleZh(orderItemDO.getProdTitleZh());
        commissionPayable.setTitleEn(orderItemDO.getProdTitleEn());
        commissionPayable.setWeight(orderItemDO.getChargeWeight());
        commissionPayable.setVolume(orderItemDO.getChargeVolume());
        commissionPayable.setQuantity(orderItemDO.getChargeQuantity().intValue());
        WarehouseLineDO warehouseLineDO = warehouseLineMapper.selectById(orderDO.getLineId());
        if (Objects.nonNull(warehouseLineDO)){
            commissionPayable.setStartWarehouseId(warehouseLineDO.getStartWarehouseId());
            commissionPayable.setDestWarehouseId(warehouseLineDO.getDestWarehouseId());
        }
        commissionPayable.setTransportId(Long.valueOf(String.valueOf(orderDO.getTransportId())));
        // 计算佣金应付金额 单价 * 收费数据 需要判断计量单位是啥
        // 获取所有单位
        List<UnitDO> unitDOList = unitService.list();
        Map<Integer, UnitDO> unitDOMap = unitDOList.stream()
                .collect(Collectors.toMap(UnitDO::getId, Function.identity(), (key1, key2) -> key2));
        UnitDO unitDO = unitDOMap.get(Integer.valueOf(orderItemDO.getSeaFreightVolume().toString()));
        if (unitDO != null) {
            if (StringUtils.equals("m³", unitDO.getFuhao())) {
                // 体积
                commissionPayable.setTotalAmount(amount.multiply(orderItemDO.getChargeVolume()).setScale(2, RoundingMode.HALF_UP));
            } else if (StringUtils.equals("kg", unitDO.getFuhao())) {
                // 重量
                commissionPayable.setTotalAmount(
                        amount.multiply(orderItemDO.getChargeWeight()).setScale(2, RoundingMode.HALF_UP));
            } else if (StringUtils.equals("a", unitDO.getFuhao())) {
                // 数量
                commissionPayable.setTotalAmount(amount.multiply(orderItemDO.getChargeQuantity()).setScale(2, RoundingMode.HALF_UP));
            } else {
                log.error("订单【{}】计价单位不存在", orderDO.getOrderNo());
            }
        }
        commissionPayable.setCurrencyId(Long.valueOf(orderItemDO.getSeaFreightCurrency()));
        // 客户信息
//        OrderConsignorDO consignorDO = orderConsignorService.getOne(new LambdaQueryWrapper<OrderConsignorDO>().eq(OrderConsignorDO::getOrderId, orderDO.getOrderId()).orderByDesc(OrderConsignorDO::getId).last("limit 1"));
//        if (Objects.nonNull(consignorDO)) {
            CustomerDO customerDO = customerService.getCustomer(orderDO.getCustomerId());
            if (Objects.nonNull(customerDO)) {
                commissionPayable.setCustomerId(customerDO.getId());
                commissionPayable.setCustomerName(customerDO.getName());
            }
//        }
        commissionPayable.setUpdateTime(new Date());
        commissionPayable.setUpdater(orderDO.getCreator());
        if (Objects.isNull(commissionPayable.getId())) {
            commissionPayable.setCreateTime(new Date());
            commissionPayable.setCreator(orderDO.getCreator());
        }
        commissionPayableService.saveOrUpdate(commissionPayable);
    }
}
