package com.yunfeiyun.agmp.fms.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.yunfeiyun.agmp.common.annotation.RedisLock;
import com.yunfeiyun.agmp.common.constant.ErrorCode;
import com.yunfeiyun.agmp.common.enums.*;
import com.yunfeiyun.agmp.common.exception.BizException;
import com.yunfeiyun.agmp.common.utils.DateUtils;
import com.yunfeiyun.agmp.common.utils.SecurityUtils;
import com.yunfeiyun.agmp.fms.domain.WmsChange;
import com.yunfeiyun.agmp.fms.domain.WmsChangeapply;
import com.yunfeiyun.agmp.fms.domain.WmsChangeapplyitem;
import com.yunfeiyun.agmp.fms.domain.WmsStock;
import com.yunfeiyun.agmp.fms.domain.resvo.*;
import com.yunfeiyun.agmp.fms.mapper.*;
import com.yunfeiyun.agmp.fms.util.DataAuthUtil;
import com.yunfeiyun.agmp.fms.domain.reqvo.WmsChangeApplyAuditReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.WmsChangeApplyGoodsListReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.WmsChangeApplyListReqVo;
import com.yunfeiyun.agmp.fms.domain.reqvo.WmsChangeApplyReqVo;
import com.yunfeiyun.agmp.fms.domain.vo.WmsAssetgoodsVo;
import com.yunfeiyun.agmp.fms.service.IWmsChangeapplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 变动申请Service业务层处理
 *
 * @author 杨晓辉
 * @date 2023-05-25
 */
@Service
public class WmsChangeapplyServiceImpl implements IWmsChangeapplyService {
    @Autowired
    private WmsChangeapplyMapper wmsChangeapplyMapper;
    @Autowired
    private WmsChangeapplyitemMapper wmsChangeapplyitemMapper;
    @Autowired
    private WmsStockMapper wmsStockMapper;
    @Autowired
    private WmsChangeMapper wmsChangeMapper;
    @Autowired
    private WmsAssetgoodsMapper wmsAssetgoodsMapper;
    @Resource
    private DataAuthUtil dataAuthUtil;


    /**
     * 查询变动申请
     *
     * @param changeapplyId 变动申请主键
     * @return 变动申请
     */
    @Override
    public WmsChangeapply selectWmsChangeapplyByChangeapplyId(String changeapplyId) {
        return wmsChangeapplyMapper.selectWmsChangeapplyByChangeapplyId(changeapplyId);
    }

    /**
     * 查询变动申请列表
     *
     * @param wmsChangeapply 变动申请
     * @return 变动申请
     */
    @Override
    public List<WmsChangeapply> selectWmsChangeapplyList(WmsChangeapply wmsChangeapply) {
        return wmsChangeapplyMapper.selectWmsChangeapplyList(wmsChangeapply);
    }

    @Override
    public List<WmsChangeApplyGoodsListResVo> selectWmsChangeApplyGoodsListResVoList(WmsChangeApplyGoodsListReqVo wmsChangeApplyGoodsListReqVo) {
        return wmsChangeapplyMapper.selectWmsChangeApplyGoodsListResVoList(wmsChangeApplyGoodsListReqVo);
    }

    @Override
    public List<WmsChangeApplyListResVo> selectWmsChangeApplyListResVoList(WmsChangeApplyListReqVo wmsChangeApplyListReqVo) {
        return wmsChangeapplyMapper.selectWmsChangeApplyListResVoList(wmsChangeApplyListReqVo);
    }

    @Override
    public WmsChangeApplyDetailsResVo selectWmsChangeapplyDetail(String changeapplyId) {
        List<JSONObject> jsonObjectList = wmsChangeapplyitemMapper.selectWmsChangeApplyDetails(changeapplyId);
        if (jsonObjectList.isEmpty()) {
            return null;
        }
        WmsChangeApplyDetailsResVo wmsChangeApplyDetailsResVo = jsonObjectList.get(0).to(WmsChangeApplyDetailsResVo.class);
        List<WmsChangeApplyDetailsResVoItem> wmsChangeapplyitemList = jsonObjectList.stream().map(jsonObject -> jsonObject.to(WmsChangeApplyDetailsResVoItem.class)).collect(Collectors.toList());
        wmsChangeApplyDetailsResVo.setWmsChangeApplyDetailsResVoItemList(wmsChangeapplyitemList);
        return wmsChangeApplyDetailsResVo;
    }

    /**
     * 新增变动申请
     *
     * @param wmsChangeapply 变动申请
     * @return 结果
     */
    @Override
    public int insertWmsChangeapply(WmsChangeapply wmsChangeapply) {
        return wmsChangeapplyMapper.insertWmsChangeapply(wmsChangeapply);
    }

    /**
     * 修改变动申请
     *
     * @param wmsChangeapply 变动申请
     * @return 结果
     */
    @Override
    public int updateWmsChangeapply(WmsChangeapply wmsChangeapply) {
        return wmsChangeapplyMapper.updateWmsChangeapply(wmsChangeapply);
    }

    /**
     * 批量删除变动申请
     *
     * @param changeapplyIds 需要删除的变动申请主键
     * @return 结果
     */
    @Override
    public int deleteWmsChangeapplyByChangeapplyIds(String[] changeapplyIds) {
        return wmsChangeapplyMapper.deleteWmsChangeapplyByChangeapplyIds(changeapplyIds);
    }

    /**
     * 删除变动申请信息
     *
     * @param changeapplyId 变动申请主键
     * @return 结果
     */
    @Override
    public int deleteWmsChangeapplyByChangeapplyId(String changeapplyId) {
        return wmsChangeapplyMapper.deleteWmsChangeapplyByChangeapplyId(changeapplyId);
    }

    /**
     * 审核变动申请
     *
     * @param wmsChangeApplyAuditReqVo 变动申请审核状态
     * @return 审核结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @RedisLock(key = RedisLockKey.STOCK_CHANGE_BIZ_LOCK)
    public int audit(WmsChangeApplyAuditReqVo wmsChangeApplyAuditReqVo) {

        WmsChangeapply wmsChangeapply = wmsChangeapplyMapper.selectWmsChangeapplyByChangeapplyId(wmsChangeApplyAuditReqVo.getChangeapplyId());
        if (!ChangeApplyAuditStatus.UNAUDITED.equal(wmsChangeapply.getChangeapplyAuditstatus())) {

            // 该申请已被审批
            throw new BizException(ErrorCode.WMS_CHANGE_APPLY_AUDIT_STATUS_ERROR);
        }
        wmsChangeapply.setChangeapplyAuditor(SecurityUtils.getUserId());
        wmsChangeapply.setChangeapplyAuditdate(DateUtils.dateTimeNow());
        wmsChangeapply.setChangeapplyAuditstatus(wmsChangeApplyAuditReqVo.getChangeApplyAuditStatus());
//        wmsChangeapply.setChangeapplyRemark(wmsChangeApplyAuditReqVo.getComments());
        wmsChangeapply.setChangeapplyComments(wmsChangeApplyAuditReqVo.getComments());
        if (ChangeApplyAuditStatus.NO_PASS.equal(wmsChangeApplyAuditReqVo.getChangeApplyAuditStatus())) {

            // 审批不通过
            return wmsChangeapplyMapper.updateWmsChangeapply(wmsChangeapply);
        }
        if (ChangeApplyAuditStatus.PASS.equal(wmsChangeApplyAuditReqVo.getChangeApplyAuditStatus())) {
            // 审批通过
            // 查询变动申请物件信息
            WmsChangeapplyitem wmsChangeapplyitem = new WmsChangeapplyitem();
            wmsChangeapplyitem.setChangeapplyId(wmsChangeapply.getChangeapplyId());
            List<WmsChangeapplyitem> wmsChangeapplyitems = wmsChangeapplyitemMapper.selectWmsChangeapplyitemList(wmsChangeapplyitem);
            // 查询变动申请物件信息关联的农资库存
            List<WmsStock> wmsStock = wmsStockMapper.selectWmsStockByChangeApplyItemList(wmsChangeapplyitems);
            // 生成变动记录，同时修改库存
            List<WmsChange> wmsChangeList = generateWmsChangeAndChangeStockAmount(wmsStock, wmsChangeapply, wmsChangeapplyitems);
            // 保存变动记录
            wmsChangeMapper.insertWmsChangeList(wmsChangeList);
            // 更新库存信息
            wmsStockMapper.updateWmsStockByBatch(wmsStock);
            // 更新变动申请
            return wmsChangeapplyMapper.updateWmsChangeapply(wmsChangeapply);
        }

        // 无效的审核状态
        throw new BizException(ErrorCode.INVALID_PARAMETER);
    }

    @Override
    public void appendChangeMessage(Map<String, FmsMessageResVo> fmsMessageResVoMap) {
        WmsChangeapply wmsChangeApplyQueryObject = new WmsChangeapply();
        wmsChangeApplyQueryObject.setDataFilter(dataAuthUtil.isValidate());
        if(wmsChangeApplyQueryObject.getDataFilter()&&!dataAuthUtil.checkRole("warehouse_admin")){
            return;
        }
        wmsChangeApplyQueryObject.setChangeapplyAuditstatus(ChangeApplyAuditStatus.UNAUDITED.getCode());
        List<WmsChangeapply> wmsChangeapplyList = wmsChangeapplyMapper.selectWmsChangeapplyList(wmsChangeApplyQueryObject);
        for (WmsChangeapply wmsChangeapply : wmsChangeapplyList) {
            FmsMessageResVo fmsMessageResVo = fmsMessageResVoMap.get(FmsMessageResVoType.CHANGE.getType());
            FmsMessageResVoItem fmsMessageResVoItem = new FmsMessageResVoItem();
            fmsMessageResVoItem.setMessageId(wmsChangeapply.getChangeapplyId());
            fmsMessageResVoItem.setMessageDate(wmsChangeapply.getChangeapplyApplydate());
            fmsMessageResVoItem.setMessageBody(wmsChangeapply);
            fmsMessageResVo.addData(fmsMessageResVoItem);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int apply(WmsChangeApplyReqVo wmsChangeApplyReqVo) {
        // 查询库存信息
        WmsStock wmsStock = wmsStockMapper.selectWmsStockByStockId(wmsChangeApplyReqVo.getStockId());
        if (null == wmsStock) {
            // 库存不存在
            throw new BizException(ErrorCode.WMS_STOCK_NOT_EXIST);
        }

        ChangeBizType bizType;
        if (wmsChangeApplyReqVo.getChangeNumber().compareTo(BigDecimal.ZERO)<0) {
            if (wmsChangeApplyReqVo.getChangeNumber().add(wmsStock.getStockAmount()).compareTo(new BigDecimal(0)) < 0) {
                // 库存不足
                throw new BizException(ErrorCode.WMS_STOCK_NOT_ENOUGH);
            }
            // 变动数量为负数，业务类型为农资申领
            bizType = ChangeBizType.REQUISITION_APPLY;
        } else {
            // 变动数量为整数，业务类型为农资退还
            bizType = ChangeBizType.RETURN_APPLY;
        }
        // 生成变动申请信息
        WmsChangeapply wmsChangeapply = new WmsChangeapply();
        wmsChangeapply.setChangeapplyId(wmsChangeapply.getId());
        // app端只能同时申请一种农资
        wmsChangeapply.setChangeapplyWay(ChangeApplyWay.SINGLE.getCode());
        wmsChangeapply.setChangeapplyBiztype(bizType.getCode());
        // 农资申领和退还无农资单价或总价，设置为0
        wmsChangeapply.setChangeapplyPricetotal(BigDecimal.ZERO);
        // 保存申请人信息和申请时间
        wmsChangeapply.setChangeapplyApplyer(SecurityUtils.getUserId());
        wmsChangeapply.setChangeapplyApplydate(DateUtils.dateTimeNow());
        // 设置审核状态和申请备注
        wmsChangeapply.setChangeapplyAuditstatus(ChangeApplyAuditStatus.UNAUDITED.getCode());
        wmsChangeapply.setChangeapplyRemark(wmsChangeApplyReqVo.getRemark());
        // 保存申请信息到数据库
        wmsChangeapplyMapper.insertWmsChangeapply(wmsChangeapply);
        // 查询农资信息
        WmsAssetgoodsVo wmsAssetGoodsVo = wmsAssetgoodsMapper.selectWmsAssetgoodsVoByGoodsId(wmsStock.getGoodsId());
        // 生成变动申请物件
        WmsChangeapplyitem wmsChangeapplyitem = new WmsChangeapplyitem();
        wmsChangeapplyitem.setChangeapplyitemId(wmsChangeapplyitem.getId());
        // 设置变动申请标识，农资标识，仓库标识
        wmsChangeapplyitem.setChangeapplyId(wmsChangeapply.getChangeapplyId());
        wmsChangeapplyitem.setGoodsId(wmsStock.getGoodsId());
        wmsChangeapplyitem.setWarehouseId(wmsStock.getWarehouseId());
        wmsChangeapplyitem.setChangeapplyitemType(wmsAssetGoodsVo.getGoodsType());
        // 设置农资相关信息
        wmsChangeapplyitem.setChangeapplyitemName(wmsAssetGoodsVo.getGoodsName());
        wmsChangeapplyitem.setChangeapplyitemUnit(wmsAssetGoodsVo.getGoodsUnit());
        wmsChangeapplyitem.setChangeapplyitemSpec(wmsAssetGoodsVo.getGoodsSpec());
        // 设置变动数量，取接口参数中的变动数量的绝对值
        wmsChangeapplyitem.setChangeapplyitemNum(wmsChangeApplyReqVo.getChangeNumber().abs());
        // 农资申领或退还不涉及金额，单价和总价统一为0
        wmsChangeapplyitem.setChangeapplyitemPriceunit(BigDecimal.ZERO);
        wmsChangeapplyitem.setChangeapplyitemPricetotal(BigDecimal.ZERO);
        // 保存变动申请物件到数据库中
        wmsChangeapplyitemMapper.insertWmsChangeapplyitem(wmsChangeapplyitem);
        return 1;
    }

    private List<WmsChange> generateWmsChangeAndChangeStockAmount(List<WmsStock> wmsStockList, WmsChangeapply wmsChangeapply, List<WmsChangeapplyitem> wmsChangeapplyitemList) {
        List<WmsChange> wmsChangeList = new ArrayList<>();
        for (WmsStock wmsStock : wmsStockList) {
            //  生成变动记录
            WmsChange wmsChange = new WmsChange();
            wmsChange.setChangeId(wmsChange.getId());
            wmsChange.setChangeapplyId(wmsChangeapply.getChangeapplyId());
            wmsChange.setStockId(wmsStock.getStockId());
            wmsChange.setChangeBiztype(wmsChangeapply.getChangeapplyBiztype());
            // 获取关联的变动申请物件信息
            List<WmsChangeapplyitem> wmsChangeapplyitems = wmsChangeapplyitemList.stream().filter(item -> item.getGoodsId().equals(wmsStock.getGoodsId()) && item.getWarehouseId().equals(wmsStock.getWarehouseId())).collect(Collectors.toList());
            if (wmsChangeapplyitems.size() != 1) {
                // 领用和归还同时只能操作一个库存信息，所以变动申请物件信息也应只有一个
                throw new BizException(ErrorCode.WMS_CHANGE_APPLY_ITEM_INVALID);
            }
            WmsChangeapplyitem wmsChangeapplyitem = wmsChangeapplyitems.get(0);
            wmsChange.setChangeNum(wmsChangeapplyitem.getChangeapplyitemNum());
            wmsChange.setChangeOldnum(wmsStock.getStockAmount());
            wmsChange.setChangeAuditor(SecurityUtils.getUserId());
            wmsChange.setChangeAuditeddate(DateUtils.dateTimeNow());
            wmsChange.setChangeRemark(wmsChangeapply.getChangeapplyRemark());
            if (ChangeBizType.REQUISITION_APPLY.equal(wmsChange.getChangeBiztype())) {
                wmsChange.setChangeNewnum(wmsChange.getChangeOldnum().subtract(wmsChange.getChangeNum()));
                if(wmsChange.getChangeNewnum().compareTo(new BigDecimal("0")) < 0){
                    throw new BizException(ErrorCode.WMS_STOCK_NOT_ENOUGH);
                }
                wmsChange.setChangeWay(ChangeWay.OUT.getCode());
            } else if (ChangeBizType.RETURN_APPLY.equal(wmsChange.getChangeBiztype())) {
                wmsChange.setChangeNewnum(wmsChange.getChangeOldnum().add(wmsChange.getChangeNum()));
                wmsChange.setChangeWay(ChangeWay.IN.getCode());
            } else {
                // 无效的变动业务类型
                throw new BizException(ErrorCode.WMS_CHANGE_APPLY_BIZ_TYPE_INVALID);
            }

            // 修改库存
            wmsStock.setStockAmount(wmsChange.getChangeNewnum());
            wmsChangeList.add(wmsChange);
        }
        return wmsChangeList;
    }
}
