package com.fjhx.purchase.service.arrival.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.enums.CodingRuleEnum;
import com.fjhx.common.service.coding.CodingRuleService;
import com.fjhx.common.utils.Assert;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.kd100.entity.company.po.CompanyInfo;
import com.fjhx.kd100.service.company.CompanyInfoService;
import com.fjhx.purchase.entity.arrival.dto.ArrivalDto;
import com.fjhx.purchase.entity.arrival.dto.ArrivalSelectDto;
import com.fjhx.purchase.entity.arrival.po.Arrival;
import com.fjhx.purchase.entity.arrival.po.ArrivalDetail;
import com.fjhx.purchase.entity.arrival.vo.ArrivalDetailVo;
import com.fjhx.purchase.entity.arrival.vo.ArrivalVo;
import com.fjhx.purchase.entity.deliver.DeliverGoodsDetailsPo;
import com.fjhx.purchase.entity.deliver.DeliverGoodsPo;
import com.fjhx.purchase.entity.purchase.po.Purchase;
import com.fjhx.purchase.entity.purchase.po.PurchaseDetail;
import com.fjhx.purchase.entity.subscribe.po.Subscribe;
import com.fjhx.purchase.entity.subscribe.po.SubscribeDetail;
import com.fjhx.purchase.mapper.arrival.ArrivalMapper;
import com.fjhx.purchase.service.WdlyService;
import com.fjhx.purchase.service.arrival.ArrivalDetailService;
import com.fjhx.purchase.service.arrival.ArrivalService;
import com.fjhx.purchase.service.purchase.PurchaseDetailService;
import com.fjhx.purchase.service.purchase.PurchaseService;
import com.fjhx.purchase.service.subscribe.SubscribeDetailService;
import com.fjhx.purchase.service.subscribe.SubscribeService;
import com.fjhx.wms.entity.stock.emums.StockWaitType;
import com.fjhx.wms.entity.stock.po.StockWait;
import com.fjhx.wms.entity.stock.po.StockWaitDetails;
import com.fjhx.wms.service.stock.StockWaitDetailsService;
import com.fjhx.wms.service.stock.StockWaitService;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * <p>
 * 到货 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-07
 */
@Service
public class ArrivalServiceImpl extends ServiceImpl<ArrivalMapper, Arrival> implements ArrivalService {

    @Autowired
    private StockWaitService stockWaitService;

    @Autowired
    private ArrivalDetailService arrivalDetailService;

    @Autowired
    private PurchaseService purchaseService;

    @Autowired
    private StockWaitDetailsService stockWaitDetailsService;

    @Autowired
    private WdlyService wdlyService;

    @Autowired
    private SubscribeDetailService subscribeDetailService;

    @Autowired
    private SubscribeService subscribeService;

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private CodingRuleService codingRuleService;

    @Override
    public Page<ArrivalVo> getPage(ArrivalSelectDto dto) {
        IWrapper<Arrival> wrapper = getWrapper();
        wrapper.orderByDesc("a", Arrival::getId);
        Page<ArrivalVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    @Override
    public ArrivalVo detail(Long id) {
        Arrival Arrival = this.getById(id);
        ArrivalVo result = BeanUtil.toBean(Arrival, ArrivalVo.class);
        return result;
    }

    /**
     * 添加
     *
     * @param arrival
     */
    @DSTransactional
    @Override
    public void add(Arrival arrival) {
        arrival.setCode(codingRuleService.createCode(CodingRuleEnum.ARRIVAL.getKey(), null));
//        arrival.setCode(CodeEnum.ARRIVAL.getCode());
        this.save(arrival);
        //修改采购状态
        Purchase purchase = new Purchase();
        purchase.setArrivalStatus(arrival.getArrivalStatus());
        purchase.setId(arrival.getPurchaseId());
        purchaseService.updateById(purchase);
        Purchase purchase1 = purchaseService.getById(arrival.getPurchaseId());
        //取出到货明细
        List<ArrivalDetail> arrivalDetailList = arrival.getArrivalDetailList();
        if (CollectionUtils.isNotEmpty(arrivalDetailList)) {
            StockWait stockWait = new StockWait();
            stockWait.setBusinessId(purchase1.getId());//采购id
            stockWait.setBusinessCode(purchase1.getCode());//采购编码
            stockWait.setType(1);//入库
            stockWait.setStatus(0);//待入库
            stockWait.setBusinessType(StockWaitType.PURCHASE_ARRIVAL_IN.getDetailType());//采购到货
            stockWaitService.save(stockWait);
            List<StockWaitDetails> stockWaitDetailsList = new ArrayList<>();
            for (ArrivalDetail d : arrivalDetailList) {
                //todo 这一块是做了采购到货状态修改。前端已经完成
                //查询采购明细
//                PurchaseDetail purchaseDetail = purchaseDetailService.getById(d.getPurchaseDetailId());
                //查询当前到货总数--修改对应得申购状态
//                BigDecimal arrivalCount = arrivalDetailService.getSumCount(d.getPurchaseDetailId(),d.getBussinessId());
//                BigDecimal sumArrivalCount = arrivalCount.add(d.getCount());
//                if(sumArrivalCount.compareTo(purchaseDetail.getCount())<0){//判断到货数量是否大于等于采购数量
//
//
//                }
                d.setArrivalId(arrival.getId());
                StockWaitDetails stockWaitDetails = new StockWaitDetails();
                stockWaitDetails.setStockWaitId(stockWait.getId());
                stockWaitDetails.setProductId(d.getBussinessId());
                stockWaitDetails.setQuantity(d.getCount());
                stockWaitDetailsList.add(stockWaitDetails);
            }
            arrivalDetailService.saveBatch(arrivalDetailList);
            stockWaitDetailsService.saveBatch(stockWaitDetailsList);
        }
    }

    /**
     * 维多利亚到货
     */
    @DSTransactional
    @Override
    public void addByWdly(ArrivalDto arrival) {
        //获取维多利亚json中的发货id
        String victoriatouristJson = arrival.getVictoriatouristJson();
        JSONObject json = ObjectUtil.isNotEmpty(victoriatouristJson) ? JSONObject.parseObject(victoriatouristJson) : new JSONObject();
        if (ObjectUtil.isEmpty(arrival.getDeliverGoodsId())) {
            arrival.setDeliverGoodsId(json.getLong("deliverGoodsId"));
        }
        //根据发货id查采购信息
        if (ObjectUtil.isNotEmpty(arrival.getDeliverGoodsId())) {
            DeliverGoodsPo deliverGoodsInfo = wdlyService.getDeliverGoodsInfo(arrival.getDeliverGoodsId());
            Assert.notEmpty(deliverGoodsInfo, "查询不到发货信息");
            arrival.setPurchaseId(deliverGoodsInfo.getPurchaseId());
        }

        if (ObjectUtil.isEmpty(arrival.getPurchaseId())) {
            throw new ServiceException("采购id不能为空");
        }
        Purchase purchase0 = purchaseService.getById(arrival.getPurchaseId());
        Assert.notEmpty(purchase0, "无法获取到采购信息");
        arrival.setSupplyId(purchase0.getSupplyId());
        arrival.setCode(codingRuleService.createCode(CodingRuleEnum.ARRIVAL.getKey(), null));
//        arrival.setCode(CodeEnum.ARRIVAL.getCode());
        arrival.setStatus(1);//设置到货
        this.save(arrival);

        //修改采购状态
//        Purchase purchase = new Purchase();
//        purchase.setArrivalStatus(arrival.getArrivalStatus());
//        purchase.setId(arrival.getPurchaseId());
//        purchaseService.updateById(purchase);

        //创建待入库记录
//        String victoriatouristJson = arrival.getVictoriatouristJson();
//        JSONObject json = ObjectUtil.isNotEmpty(victoriatouristJson) ? JSONObject.parseObject(victoriatouristJson) : new JSONObject();
        Long deliverGoodsId = json.getLong("deliverGoodsId");

        if (ObjectUtil.isEmpty(deliverGoodsId)) {
            throw new ServiceException("发货id不能为空");
        }

        //查询发货信息 获取 采购id
        DeliverGoodsPo deliverGoodsInfo = wdlyService.getDeliverGoodsInfo(deliverGoodsId);

        //去申购单取入库仓库id
        PurchaseDetail one = purchaseDetailService.getOne(q -> q.eq(PurchaseDetail::getPurchaseId, deliverGoodsInfo.getPurchaseId()));
        Long subscribeDetailId = one.getSubscribeDetailId();
        SubscribeDetail byId = subscribeDetailService.getById(subscribeDetailId);
        Subscribe byId1 = subscribeService.getById(byId.getSubscribeId());
        String victoriatouristJson1 = byId1.getVictoriatouristJson();
        if (ObjectUtil.isNotEmpty(victoriatouristJson1)) {
            //去申购单取仓库id
            JSONObject json1 = JSONObject.parseObject(victoriatouristJson1);
            Long receiptWarehouseId = json1.getLong("receiptWarehouseId");
            json.put("receiptWarehouseId", receiptWarehouseId);
        }
        //赋值物流公司名称
        CompanyInfo logisticsCompanyCode = companyInfoService.getOne(q -> q.eq(CompanyInfo::getCode, json.getString("logisticsCompanyCode")));
        json.put("logisticsCompanyName", logisticsCompanyCode.getName());
        //修改发货记录的状态为到货
        wdlyService.updateDeliverGoodsStatus(deliverGoodsId);

        //获取采购信息
        Purchase purchase = purchaseService.getById(deliverGoodsInfo.getPurchaseId());

        //----------
        StockWait stockWait = new StockWait();
        stockWait.setType(1);//入库
        stockWait.setStatus(0);//待入库
        stockWait.setBusinessType(StockWaitType.PURCHASE_ARRIVAL_IN.getDetailType());//采购到货
        //将业务信息设置成采购id和采购编码
        stockWait.setBusinessId(purchase.getId());
        String victoriatouristJson2 = purchase.getVictoriatouristJson();
        JSONObject json2 = ObjectUtil.isNotEmpty(victoriatouristJson2) ? JSONObject.parseObject(victoriatouristJson2) : new JSONObject();
//        stockWait.setBusinessCode(purchase.getCode());
        stockWait.setBusinessCode(json2.getString("contractCode"));

        json.put("arrivalId", arrival.getId());
        json.put("arrivalCode", arrival.getCode());
        stockWait.setVictoriatouristJson(JSONObject.toJSONString(json,JSONWriter.Feature.WriteLongAsString));
        stockWaitService.save(stockWait);

        //取出到货明细
        List<ArrivalDetail> arrivalDetailList = arrival.getArrivalDetailList();
        if (CollectionUtils.isEmpty(arrivalDetailList)) {
            return;
        }

        List<StockWaitDetails> stockWaitDetailsList = new ArrayList<>();
        List<Long> arrivalDids = arrivalDetailList.stream().map(ArrivalDetail::getPurchaseDetailId).collect(Collectors.toList());
        List<PurchaseDetail> purchaseDetailList = purchaseDetailService.listByIds(arrivalDids);
        if (ObjectUtil.isNotEmpty(purchaseDetailList)) {
            Map<Long, PurchaseDetail> purchaseDetailMap = purchaseDetailList.stream().collect(Collectors.toMap(PurchaseDetail::getId, Function.identity()));
            //获取发货明细
            List<DeliverGoodsDetailsPo> deliverGoodsDetailsInfo = wdlyService.getDeliverGoodsDetailsInfo(deliverGoodsId);
            Map<Long, DeliverGoodsDetailsPo> deliverGoodsDetailsInfoMap = deliverGoodsDetailsInfo.stream().collect(Collectors.toMap(DeliverGoodsDetailsPo::getId, Function.identity()));
            int flag = 0;//到货数量不等于发货数量计数
            for (ArrivalDetail d : arrivalDetailList) {
                Long id = IdWorker.getId();
                d.setId(id);
                d.setArrivalId(arrival.getId());

                Long deliverGoodsDetailsId = d.getDeliverGoodsDetailsId();
                DeliverGoodsDetailsPo deliverGoodsDetailsPo = deliverGoodsDetailsInfoMap.get(deliverGoodsDetailsId);
                if (ObjectUtil.isEmpty(deliverGoodsDetailsPo)) {
                    throw new ServiceException("未找到发货明细信息");
                }

                //如果到货数量不等于发货数量 创建异常
                if (deliverGoodsDetailsPo.getDeliverGoodsQuantity().compareTo(d.getCount()) != 0) {
                    flag++;
                }

                StockWaitDetails stockWaitDetails = new StockWaitDetails();
                stockWaitDetails.setStockWaitId(stockWait.getId());
                //业务明细id设置成到货明细id
                stockWaitDetails.setBusinessDetailsId(d.getId());
                stockWaitDetails.setProductId(d.getBussinessId());
                stockWaitDetails.setQuantity(d.getCount());
                //赋值已采购数量信息
                PurchaseDetail byId2 = purchaseDetailMap.get(d.getPurchaseDetailId());
                BigDecimal count = byId2.getCount();
                stockWaitDetails.setPurchaseQuantity(count);
                stockWaitDetailsList.add(stockWaitDetails);
            }

            //存在到货数量不等于发货数量 创建异常
            if (flag != 0) {
                wdlyService.addAbnormalInfo(arrival.getId(), arrival.getCode());
            }
        }
        arrivalDetailService.saveBatch(arrivalDetailList);
        DynamicDataSourceContextHolder.push(SourceConstant.WMS);
        stockWaitDetailsService.saveBatch(stockWaitDetailsList);
        DynamicDataSourceContextHolder.poll();

        //修改到货状态
//        Integer flag = 0;
//        List<PurchaseDetail> purchaseDetailsList1 = purchaseDetailService.list(q -> q.eq(PurchaseDetail::getPurchaseId, purchase.getId()));
//        if (ObjectUtil.isNotEmpty(purchaseDetailsList1)) {
//            List<Long> purchaseDetailsIds = purchaseDetailsList1.stream().map(PurchaseDetail::getId).collect(Collectors.toList());
//            List<ArrivalDetail> arrivalDetailsList1 = arrivalDetailService.list(q -> q.in(ArrivalDetail::getPurchaseDetailId, purchaseDetailsIds));
//            if (ObjectUtil.isNotEmpty(arrivalDetailsList1)) {
//                Map<Long, List<ArrivalDetail>> arrivalDetailsMap = arrivalDetailsList1.stream().collect(Collectors.groupingBy(ArrivalDetail::getPurchaseDetailId));
//                for (PurchaseDetail purchaseDetail : purchaseDetailsList1) {
//                    List<ArrivalDetail> arrivalDetails = arrivalDetailsMap.get(purchaseDetail.getId());
//                    BigDecimal count = arrivalDetails.stream()
//                            .map(ArrivalDetail::getCount)
//                            .reduce(BigDecimal.ZERO, BigDecimal::add);
//                    if (count.compareTo(purchaseDetail.getCount()) >= 0) {
//                        flag++;
//                    }
//                }
//                if (purchaseDetailsList1.size() == flag) {
//                    //完全到货
//                    purchase.setArrivalStatus(20);
//                } else {
//                    //部分到货
//                    purchase.setArrivalStatus(10);
//                }
//                purchaseService.updateById(purchase);
//            }
//        }
    }

    @Override
    public void edit(ArrivalDto arrivalDto) {
        this.updateById(arrivalDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

    /**
     * 根据发货id获取本次发货的到货信息
     */
    @Override
    public ArrivalVo arrivalInfo(Long deliverGoodsId) {
        Assert.notEmpty(deliverGoodsId,"发货id不能为空");
        ArrivalVo arrival = baseMapper.arrivalInfo(deliverGoodsId);
        Assert.notEmpty(arrival, "查询不到到货信息");
        List<ArrivalDetail> arrivalDetailList = arrivalDetailService.list(q -> q.eq(ArrivalDetail::getArrivalId, arrival.getId()));
        List<ArrivalDetailVo> arrivalDetailVos = BeanUtil.copyToList(arrivalDetailList, ArrivalDetailVo.class);
        //赋值产品信息
        productInfoService.attributeAssign(arrivalDetailVos, ArrivalDetailVo::getBussinessId, (item, productInfo) -> {
            item.setProductName(productInfo.getName());
            item.setProductCustomCode(productInfo.getCustomCode());
        });
        arrival.setArrivalDetailVoList(arrivalDetailVos);
        return arrival;
    }

}
