package com.fjhx.sale.flow;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.fjhx.common.entity.AvailableStockBo;
import com.fjhx.common.enums.CodingRuleEnum;
import com.fjhx.common.enums.FlowStatusEnum1;
import com.fjhx.common.service.coding.CodingRuleService;
import com.fjhx.flow.core.FlowDelegate;
import com.fjhx.flow.enums.FlowStatusEnum;
import com.fjhx.item.enums.ProductAvailableRecordType;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.sale.entity.purchase.dto.PurchaseBackDto;
import com.fjhx.sale.entity.purchase.po.PurchaseBack;
import com.fjhx.sale.entity.purchase.po.PurchaseBackDetails;
import com.fjhx.sale.service.purchase.PurchaseBackDetailsService;
import com.fjhx.sale.service.purchase.PurchaseBackService;
import com.fjhx.wms.entity.stock.emums.JournalType;
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.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class PurchaseBackFlow extends FlowDelegate {

    @Autowired
    private CodingRuleService codingRuleService;
    @Autowired
    private PurchaseBackService purchaseBackService;
    @Autowired
    private PurchaseBackDetailsService purchaseBackDetailsService;
    @Autowired
    private StockWaitService stockWaitService;
    @Autowired
    private StockWaitDetailsService stockWaitDetailsService;
    @Autowired
    private ProductInfoService productInfoService;

    @Override
    public String getFlowKey() {
        return "purchase_back_flow";
    }

    @Override
    public Long start(Long flowId, JSONObject submitData) {
        PurchaseBackDto purchaseBackDto = submitData.toJavaObject(PurchaseBackDto.class);

        purchaseBackDto.setCompanyId(SecurityUtils.getCompanyId());

        //赋值编号
        if (ObjectUtil.isEmpty(purchaseBackDto.getId())) {
            purchaseBackDto.setCode(codingRuleService.createCode(CodingRuleEnum.PURCHASE_BACK.getKey(), null));
        }

        //改成审批中
        purchaseBackDto.setStatus(FlowStatusEnum1.UNDER_REVIEW.getKey());

        purchaseBackService.saveOrUpdate(purchaseBackDto);
        List<PurchaseBackDetails> purchaseBackDetailsList = purchaseBackDto.getPurchaseBackDetailsList();

        //过滤退货数量为空或0的数据
        purchaseBackDetailsList = purchaseBackDetailsList.stream()
                .filter(item -> ObjectUtil.isNotEmpty(item.getQuantity()) && item.getQuantity().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());

        for (PurchaseBackDetails purchaseBackDetails : purchaseBackDetailsList) {
            purchaseBackDetails.setPurchaseBackId(purchaseBackDto.getId());
            purchaseBackDetails.setPurchaseId(purchaseBackDto.getPurchaseId());
        }
        purchaseBackDetailsService.saveOrUpdateBatch(purchaseBackDetailsList);

        //回传单号
        submitData.put("code", purchaseBackDto.getCode());
        return purchaseBackDto.getId();
    }

    @Override
    public void end(Long flowId, Long businessId, JSONObject submitData) {
        PurchaseBack purchaseBack = purchaseBackService.getById(businessId);
        purchaseBack.setStatus(FlowStatusEnum1.PASS.getKey());
        purchaseBackService.updateById(purchaseBack);

        //创建待出库
        StockWait stockWait = new StockWait();
        stockWait.setType(2);//出库
        stockWait.setStatus(0);//待出库
        stockWait.setBusinessType(JournalType.PURCHASE_RETURN_OUT.getDetailType());
        stockWait.setBusinessId(purchaseBack.getId());
        stockWait.setBusinessCode(purchaseBack.getCode());
        stockWaitService.save(stockWait);

        List<StockWaitDetails> stockWaitDetailsList = new ArrayList<>();
        List<AvailableStockBo> availableStockBoList = new ArrayList<>();

        List<PurchaseBackDetails> list = purchaseBackDetailsService.list(q -> q.eq(PurchaseBackDetails::getPurchaseBackId, businessId));
        for (PurchaseBackDetails purchaseBackDetails : list) {
            Long productId = purchaseBackDetails.getProductId();
            BigDecimal quantity = purchaseBackDetails.getQuantity();
            //生成待出库
            StockWaitDetails stockWaitDetails = new StockWaitDetails();
            stockWaitDetails.setStockWaitId(stockWait.getId());
            stockWaitDetails.setProductId(productId);
            stockWaitDetails.setQuantity(quantity);
            stockWaitDetailsList.add(stockWaitDetails);


            //生成操作可用库存的实体
            AvailableStockBo availableStockBo = new AvailableStockBo();
            availableStockBo.setProductId(productId);
            availableStockBo.setQuantity(quantity);
            availableStockBoList.add(availableStockBo);
        }
        stockWaitDetailsService.saveBatch(stockWaitDetailsList);

        //修改可用库存
        productInfoService.editAvailableQuantity(availableStockBoList, businessId, ProductAvailableRecordType.PURCHASE_BACK, purchaseBack.getCompanyId());
    }

    @Override
    public void relaunch(Long flowId, Long businessId, FlowStatusEnum flowStatus, JSONObject submitData) {
        start(flowId, submitData);
    }

    @Override
    public void reject(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        //作废
        purchaseBackService.update(q -> q
                .eq(PurchaseBack::getId, businessId)
                .set(PurchaseBack::getStatus, FlowStatusEnum1.REJECT.getKey())
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
    }

    @Override
    public void cancellation(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        //作废
        purchaseBackService.update(q -> q
                .eq(PurchaseBack::getId, businessId)
                .set(PurchaseBack::getStatus, FlowStatusEnum1.CANCELLATION.getKey())
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
    }
}
