package com.fjhx.purchase.flow;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.enums.CodingRuleEnum;
import com.fjhx.common.enums.FlowStatusEnum1;
import com.fjhx.common.service.coding.CodingRuleService;
import com.fjhx.common.utils.Assert;
import com.fjhx.flow.core.FlowDelegate;
import com.fjhx.flow.enums.FlowStatusEnum;
import com.fjhx.purchase.entity.sales.enums.SalesReturnDetailStatusEnum;
import com.fjhx.purchase.entity.sales.enums.SalesReturnStatusEnum;
import com.fjhx.purchase.entity.sales.po.SalesReturn;
import com.fjhx.purchase.entity.sales.po.SalesReturnDetail;
import com.fjhx.purchase.service.sales.SalesReturnDetailService;
import com.fjhx.purchase.service.sales.SalesReturnService;
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.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 退货流程
 *
 * @Author:caozj
 * @DATE:2023/4/3 17:38
 */
@DS(SourceConstant.PURCHASE)
@Component
public class SalesReturnFlow extends FlowDelegate {

    @Autowired
    StockWaitDetailsService stockWaitDetailsService;

    @Autowired
    private CodingRuleService codingRuleService;

    @Autowired
    private SalesReturnService salesReturnService;
    @Autowired
    private SalesReturnDetailService salesReturnDetailService;

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


    /**
     * 发起流程
     *
     * @param flowId     流程ID
     * @param submitData 数据
     * @return
     */
    @Override
    public Long start(Long flowId, JSONObject submitData) {

        SalesReturn salesReturn = submitData.toJavaObject(SalesReturn.class);
        salesReturn.setCode(codingRuleService.createCode(CodingRuleEnum.SALES_RETURN.getKey(), null));
        salesReturn = commStart(salesReturn, 0);

        return salesReturn.getId();
    }

    /**
     * 开始公共代码抽取
     *
     * @param opType 操作类型 0直接发起 1重新发起
     */
    private SalesReturn commStart(SalesReturn salesReturn, Integer opType) {
        if (opType == 1) {
            Assert.notEmpty(salesReturn.getId(), "退货id不能为空");
        }
        salesReturnService.saveOrUpdate(salesReturn);
        List<SalesReturnDetail> salesReturnDetailList = salesReturn.getSalesReturnDetailList();
        if (CollectionUtils.isNotEmpty(salesReturnDetailList)) {
            if (opType == 1) {
                //先删除被删除的产品
                salesReturnDetailService.editLinked(salesReturnDetailList, SalesReturnDetail::getSalesReturnId, salesReturn.getId());
            }
            for (SalesReturnDetail s : salesReturnDetailList) {
                s.setSalesReturnId(salesReturn.getId());
            }
            salesReturnDetailService.saveOrUpdateBatch(salesReturnDetailList);
        }
        return salesReturn;
    }

    /**
     * 结束流程
     *
     * @param flowId     流程ID
     * @param businessId 业务ID
     * @param submitData 数据
     */
    @Override
    public void end(Long flowId, Long businessId, JSONObject submitData) {
        SalesReturnService salesReturnService = SpringUtil.getBean(SalesReturnService.class);
        SalesReturnDetailService salesReturnDetailService = SpringUtil.getBean(SalesReturnDetailService.class);
        StockWaitService stockWaitService = SpringUtil.getBean(StockWaitService.class);
        //通过业务ID查询退货数据
        SalesReturn salesReturn = salesReturnService.getById(businessId);
        if (ObjectUtils.isEmpty(salesReturn)) {
            throw new ServiceException("退货单单不存在");
        }
        //修改退货状态为待退货
        salesReturn.setStatus(SalesReturnStatusEnum.PASS.getKey());
        salesReturn.setApprovedDate(new Date());
        salesReturnService.updateById(salesReturn);
        //修改退货明细状态为待退货
        SalesReturnDetail detail = new SalesReturnDetail();
        detail.setStatus(SalesReturnDetailStatusEnum.STATUS_20.getKey());
        salesReturnDetailService.update(detail, Wrappers.<SalesReturnDetail>query()
                .lambda().eq(SalesReturnDetail::getSalesReturnId, salesReturn.getId()));
        List<SalesReturnDetail> salesReturnDetailList = salesReturnDetailService.list(Wrappers.<SalesReturnDetail>query()
                .lambda().eq(SalesReturnDetail::getSalesReturnId, salesReturn.getId()));
        //添加一份待出库数据
        StockWait stockWait = new StockWait();
        stockWait.setBusinessId(businessId);
        stockWait.setType(2);//入库
        stockWait.setStatus(0);//待入库
        stockWait.setBusinessType(StockWaitType.BACK_OUT.getDetailType());//退货出库
        stockWaitService.save(stockWait);
        List<StockWaitDetails> stockWaitDetailsList = new ArrayList<>();
        for (SalesReturnDetail s : salesReturnDetailList) {
            StockWaitDetails stockWaitDetails = new StockWaitDetails();
            stockWaitDetails.setStockWaitId(stockWait.getId());
            stockWaitDetails.setProductId(s.getBussinessId());
            stockWaitDetails.setBusinessDetailsId(s.getId());//到货明细ID
            stockWaitDetails.setQuantity(s.getCount());
            stockWaitDetailsList.add(stockWaitDetails);
        }
        stockWaitDetailsService.saveBatch(stockWaitDetailsList);
    }

    @Override
    public void relaunch(Long flowId, Long businessId, FlowStatusEnum flowStatus, JSONObject submitData) {
        super.relaunch(flowId, businessId, flowStatus, submitData);
        SalesReturn salesReturn = submitData.toJavaObject(SalesReturn.class);
        commStart(salesReturn, 1);
    }

    @Override
    public void reject(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        super.reject(flowId, businessId, flowStatus);

        salesReturnService.update(q -> q
                .eq(SalesReturn::getId, businessId)
                .set(SalesReturn::getStatus, FlowStatusEnum1.REJECT.getKey())
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
    }

    @Override
    public void cancellation(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        super.cancellation(flowId, businessId, flowStatus);

        salesReturnService.update(q -> q
                .eq(SalesReturn::getId, businessId)
                .set(SalesReturn::getStatus, FlowStatusEnum1.CANCELLATION.getKey())
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
    }
}
