package com.jwipc.contract.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jwipc.constant.DelFlag;
import com.jwipc.contract.convert.ContractDeliveryDetailConvert;
import com.jwipc.contract.dto.ContractDeliveryDetailDTO;
import com.jwipc.contract.dto.ContractOrderQuantityDTO;
import com.jwipc.contract.entity.ContractDelivery;
import com.jwipc.contract.entity.ContractDeliveryDetail;
import com.jwipc.contract.entity.ContractDetail;
import com.jwipc.contract.entity.ContractReturnOrderDetail;
import com.jwipc.contract.logic.ContractDeliveryDetailLogic;
import com.jwipc.contract.logic.ContractDeliveryLogic;
import com.jwipc.contract.model.po.ContractDeliveryDetailPO;
import com.jwipc.contract.model.query.ContractDeliveryDetailQuery;
import com.jwipc.contract.service.IContractDeliveryDetailService;
import com.jwipc.contract.service.IContractDeliveryService;
import com.jwipc.contract.service.IContractReturnOrderDetailService;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@RequiredArgsConstructor
@Slf4j
public class ContractDeliveryDetailLogicImpl implements ContractDeliveryDetailLogic {

    private final IContractDeliveryDetailService contractDeliveryDetailService;
    private final IContractDeliveryService contractDeliveryService;
    private final IContractReturnOrderDetailService contractReturnOrderDetailService;
    private final ContractDeliveryDetailConvert contractDeliveryDetailConvert;
    private final ContractDeliveryLogic contractDeliveryLogic;
    @Override
    public PageView getListDeliverDetail(Long id) {
        ContractDeliveryDetailQuery query = new ContractDeliveryDetailQuery();
        query.setDeliveryId(id);
        List<ContractDeliveryDetailPO> list =  contractDeliveryDetailService.findList(query);
        List<ContractDeliveryDetailDTO> dtos = contractDeliveryDetailConvert.pos2Dtos(list);
        return PageUtil.getPV(dtos, dtos.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(String ids) {
        final List<String> idList = StrUtil.split(ids, StrUtil.COMMA);
        if (CollUtil.isNotEmpty(idList)) {
            contractDeliveryDetailService.update(
                    new LambdaUpdateWrapper<ContractDeliveryDetail>().set(ContractDeliveryDetail::getDeleteFlag,
                            DelFlag.DELETE.getStatus()).
                            set(ContractDeliveryDetail:: getUpdateId,LoginUtil.getUserId()).
                            set(ContractDeliveryDetail:: getUpdateTime,LocalDateTime.now())
                            .in(ContractDeliveryDetail::getId, idList));
            final ContractDeliveryDetail detail = contractDeliveryDetailService.getById(idList.get(0));
            long count = contractDeliveryDetailService.count(
                    new LambdaQueryWrapper<ContractDeliveryDetail>().eq(ContractDeliveryDetail::getDeliveryId,
                            detail.getDeliveryId()).eq(ContractDeliveryDetail::getDeleteFlag, DelFlag.NORMAL.getStatus()));
            if (count == 0L) {
                contractDeliveryService.update(new LambdaUpdateWrapper<ContractDelivery>().set(ContractDelivery::getDeleteFlag,
                        DelFlag.DELETE.getStatus())
                        .set(ContractDelivery:: getUpdateId,LoginUtil.getUserId())
                        .set(ContractDelivery:: getUpdateTime,LocalDateTime.now())
                        .eq(ContractDelivery::getId, detail.getDeliveryId()));
            }
            //不需要推送共享，单据只有在创建状态才可以编辑删除，推送共享后不允许在原档编辑删除
        }
    }

    @Override
    public PageView selectContractDeliveryListPage(ContractDeliveryDetailQuery query) {
        final Page<ContractDeliveryDetail> page = PageUtil.toPage(query);
        List<ContractDeliveryDetail> details = contractDeliveryDetailService.selectReceiptContractDetailListPage(page,query);
        return PageUtil.getPV(details, page.getTotal());
    }

    @Override
    public PageView selectreturnOrdertDetailListPage(ContractDeliveryDetailQuery query) {
        final Page<ContractDeliveryDetail> page = PageUtil.toPage(query);
        List<ContractDeliveryDetail> details = contractDeliveryDetailService.selectreturnOrdertDetailListPage(page,query);
        List<String> dataKeys = details.stream()
                .map(d -> d.getContractNo() + "_" + d.getContractSeq())
                .distinct()
                .collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(dataKeys)){
            ContractOrderQuantityDTO contactOrderNumData = contractDeliveryLogic.findContactOrderNumData(dataKeys);
            Map<String, BigDecimal> receiveNumMap = contactOrderNumData.getReceiveNumMap();
            Map<String, BigDecimal> returntMap = contactOrderNumData.getReturntMap();
            for (ContractDeliveryDetail detail : details) {
                //统计已退数量
                //统计可退数量
                //统计收货数量
                String key = detail.getContractNo()+"_"+detail.getContractSeq();
                BigDecimal receivedQuantity = receiveNumMap.get(key);
                BigDecimal returnedQuantity = returntMap.get(key) ;
                BigDecimal returnableQuantity = (receivedQuantity == null ? BigDecimal.ZERO.stripTrailingZeros() : receivedQuantity).subtract((returnedQuantity == null ? BigDecimal.ZERO.stripTrailingZeros() : returnedQuantity));
                BigDecimal returnQuantity = returnableQuantity;
                //收货数量
                detail.setReceivedQuantity(receivedQuantity == null ? BigDecimal.ZERO.stripTrailingZeros() : receivedQuantity);
                //已退数量
                detail.setReturnedQuantity(returnedQuantity);
                //可退数量
                detail.setReturnableQuantity(returnableQuantity);
                //退货数量
                detail.setReturnQuantity(returnQuantity);
            }
        }

        return PageUtil.getPV(details, page.getTotal());
    }
}
