package com.prolog.upcloud.base.wh.operate.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.codingapi.tx.annotation.TxTransaction;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.upcloud.base.inventory.model.WmsInvStockLot;
import com.prolog.upcloud.base.inventory.vo.BatchNumberListVO;
import com.prolog.upcloud.base.inventory.vo.StockLotLockVO;
import com.prolog.upcloud.base.wh.operate.constant.InvLockConstant;
import com.prolog.upcloud.base.wh.operate.dao.WmsInvStockLockMapper;
import com.prolog.upcloud.base.wh.operate.dto.LockStockDTO;
import com.prolog.upcloud.base.wh.operate.dto.UnLockStockDTO;
import com.prolog.upcloud.base.wh.operate.model.WmsInvStockLock;
import com.prolog.upcloud.base.wh.operate.resource.GspClient;
import com.prolog.upcloud.base.wh.operate.resource.StockResource;
import com.prolog.upcloud.base.wh.operate.service.InvStockLockService;
import com.prolog.upcloud.base.wh.operate.service.UserService;
import com.prolog.upcloud.base.wh.operate.utils.DateUtils;
import com.prolog.upcloud.base.wh.operate.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class InvStockLockServiceImpl implements InvStockLockService {


    @Resource
    private WmsInvStockLockMapper wmsInvStockLockMapper;

    @Resource
    private StockResource stockResource;

    @Resource
    private UserService userService;

    @Resource
    private GspClient gspClient;

    //自动锁定接口开发
    @TxTransaction
    @Transactional(rollbackFor = Exception.class)
    public void autoStockInfo(String enterpriseid, String warehouseid) {
        //查询待锁定库存
        RestMessage<List<WmsInvStockLot>> restInvStockLotMsg = stockResource.getExpireStockList(enterpriseid, warehouseid);
        if (restInvStockLotMsg.isSuccess() == false ){
            throw new RuntimeException(restInvStockLotMsg.getMessage());
        }
        List<WmsInvStockLot> wmsInvStockLotList = restInvStockLotMsg.getData();
        List<WmsInvStockLock> wmsInvStockLocks = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        //锁定库存
        for (WmsInvStockLot wmsInvStockLot : wmsInvStockLotList) {
            WmsInvStockLock wmsInvStockLock = null;
            Criteria  criteria=Criteria.forClass(WmsInvStockLock.class);
            criteria.setRestriction(Restrictions.eq("stockaccno",wmsInvStockLot.getId()));
            List<WmsInvStockLock> wmsInvStockLockList= wmsInvStockLockMapper.findByCriteria(criteria);
            if(wmsInvStockLockList!=null&&wmsInvStockLockList.size()>0){
                wmsInvStockLock=wmsInvStockLockList.get(0);
            }else{
                wmsInvStockLock=new WmsInvStockLock();
            }
            wmsInvStockLock.setCreateby("sys");
            wmsInvStockLock.setCreatedate(DateUtils.getNowDate());
            wmsInvStockLock.setLocktype(InvLockConstant.LOCKTYPE_AUTO);//自动锁定
            wmsInvStockLock.setStockaccno(wmsInvStockLot.getId());
            wmsInvStockLock.setLockreason("1");//默认1
            wmsInvStockLock.setLockoper(InvLockConstant.LOCKOPER_LOCK);//锁定操作
            wmsInvStockLock.setLockqty(wmsInvStockLot.getQuantity().doubleValue());//锁定数量
            if(!StringUtils.isBlank(wmsInvStockLock.getId()) ){
                wmsInvStockLockMapper.update(wmsInvStockLock);
            }else{
                wmsInvStockLocks.add(wmsInvStockLock);
            }

            ids.add(wmsInvStockLot.getId());
        }

        //调用basic服务锁定库存
        StockLotLockVO vo = new StockLotLockVO();
        vo.setIds(ids);
        stockResource.lockStockLot(vo);
        if(wmsInvStockLocks.size()>0){
            //插入锁定记录表
            wmsInvStockLockMapper.saveBatch(wmsInvStockLocks);
        }

        //回传ERP
        wmsInvStockLockToErp(wmsInvStockLotList,wmsInvStockLocks,"");//todo 确定接口
    }


    //手动锁定确认接口开发
    @TxTransaction(isStart = true)
    @Transactional(rollbackFor = Exception.class)
    public void lockStockInfo(List<LockStockDTO> dtos) {
        UserDTO userDTO = userService.getUser();
        List<String> ids = new ArrayList<>();
        List<WmsInvStockLock> wmsInvStockLocks = new ArrayList<>();
        List<WmsInvStockLock> wmsInvStockLocks1 = new ArrayList<>();
        for (LockStockDTO dto : dtos) {
            WmsInvStockLock wmsInvStockLock = null;
            Criteria  criteria=Criteria.forClass(WmsInvStockLock.class);
            criteria.setRestriction(Restrictions.eq("stockaccno",dto.getId()));
            List<WmsInvStockLock> wmsInvStockLockList= wmsInvStockLockMapper.findByCriteria(criteria);
            if(wmsInvStockLockList!=null&&wmsInvStockLockList.size()>0){
                wmsInvStockLock=wmsInvStockLockList.get(0);
            }else{
                wmsInvStockLock=new WmsInvStockLock();
            }
            wmsInvStockLock.setCreateby(userDTO.getId());
            wmsInvStockLock.setCreatedate(DateUtils.getNowDate());
            wmsInvStockLock.setLocktype(InvLockConstant.LOCKTYPE_MANUL);//手动锁定
            wmsInvStockLock.setLockreason(dto.getLockreason());
            wmsInvStockLock.setStockaccno(dto.getId());
            wmsInvStockLock.setLockoper(InvLockConstant.LOCKOPER_LOCK);//锁定操作
            wmsInvStockLock.setLockqty(dto.getLockqty());
            ids.addAll(Arrays.asList(dto.getId().split(",")));
            if(!StringUtils.isBlank(wmsInvStockLock.getId())){
                wmsInvStockLockMapper.update(wmsInvStockLock);
            }else{
                wmsInvStockLocks.add(wmsInvStockLock);
            }
            wmsInvStockLocks1.add(wmsInvStockLock);
        }
        //调用basic服务锁定库存
        StockLotLockVO vo = new StockLotLockVO();
        vo.setIds(ids);
        RestMessage restMessage=stockResource.lockStockLot(vo);
        if(restMessage.isSuccess()==false){
            throw new RuntimeException(restMessage.getMessage());
        }
        if(wmsInvStockLocks.size()>0){
            //写入库存锁定记录表
            wmsInvStockLockMapper.saveBatch(wmsInvStockLocks);
        }

        //回传ERP接口
        RestMessage<List<WmsInvStockLot>> stockResourceStockListByIds= stockResource.getStockListByIds(ids.toArray
                (new String[ids.size()]));

        if(stockResourceStockListByIds.isSuccess()==false||stockResourceStockListByIds.getData().size()==0){
            throw new RuntimeException("没有找到需要处理库存！");
        }
        if(CollUtil.isEmpty(wmsInvStockLocks1)){
            throw new RuntimeException("没有找到锁定单！");
        }
        List<WmsInvStockLot> stockLots = stockResourceStockListByIds.getData();
        wmsInvStockLockToErp(stockLots,wmsInvStockLocks1,"");

    }

    public void wmsInvStockLockToErp(List<WmsInvStockLot> stockLots,List<WmsInvStockLock> stockLocks,String url){
        List<Map<String, Object>> toErpParams = new ArrayList<>();
        List<String> batchId = stockLots.stream().map(WmsInvStockLot::getBatchId).collect(Collectors.toList());
        RestMessage<List<BatchNumberListVO>> batchNumberBasicInfo = stockResource.getBatchNumberBasicInfo(batchId.toArray(new String[batchId.size()]));
        if (!batchNumberBasicInfo.isSuccess() || batchNumberBasicInfo.getData() == null) {
            throw new BizException("查询批次关联信息失败!请重试或联系管理员!");
        }
        List<BatchNumberListVO> batchNumberListVOS = batchNumberBasicInfo.getData();
        for (WmsInvStockLot lot:stockLots) {
            WmsInvStockLock stockLock = stockLocks.stream().filter(ls-> ls.getStockaccno().contains(lot.getId()))
                    .findFirst().orElse(null);
            BatchNumberListVO vo = batchNumberListVOS.stream().filter(ls-> lot.getBatchId().equals(ls.getBatchId()))
                    .findFirst().orElse(null);
            Map<String, Object> toErpParam = new HashMap<>();
            toErpParam.put("djbh",stockLock.getId());//单据编号
            toErpParam.put("danwbh",vo.getPieceUom());//单位编号
            toErpParam.put("branchid",lot.getWarehouseId());//仓ID
            toErpParam.put("ddlx",stockLock.getLockoper());//单据类型(1锁定，二解锁)
            toErpParam.put("ywlx",2);//0-物料，1-物料批次，2-物料批次货位待确认
            toErpParam.put("dj_sort",stockLock.getId());
            toErpParam.put("spid",lot.getItemId());
            toErpParam.put("ph",lot.getBatchNum());
            toErpParam.put("sl",stockLock.getLockqty());
            toErpParam.put("rq_sc",com.prolog.framework.utils.DateUtils.format(vo.getBatchProductionDate(),"yyyy-MM-dd"));
            toErpParam.put("yxqz",com.prolog.framework.utils.DateUtils.format(vo.getBatchExpiredDate(),"yyyy-MM-dd"));
            toErpParam.put("sdyy",stockLock.getLockreason());
            toErpParam.put("dmrq",com.prolog.framework.utils.DateUtils.format(stockLock.getCreatedate(),"yyyy-MM-dd HH:mm:ss"));
            toErpParam.put("wmflg","Y");
            toErpParam.put("xgtime", com.prolog.framework.utils.DateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"));
            toErpParams.add(toErpParam);
        }
//        JSONObject object = integrationUtil.askIntegration("/api/siyuan/warehouse/wmsInvStockLockToErp", Collections.singletonMap("list", toErpParams));
//        if (!object.getString("success").equals("true")){
//            throw new BizException("回写失败"+JSONObject.toJSONString(toErpParams)+JSONObject.toJSONString(object));
//        }
    }

    @TxTransaction
    @Transactional(rollbackFor = Exception.class)
    public void unlockStockInfo(UnLockStockDTO dto) {

        UserDTO userDTO = userService.getUser();
        //调用basic服务解锁库存
        //确认后则解锁库存 ，处理锁定数量、锁定标识、清空锁定类型、锁定原因
        com.prolog.upcloud.base.wh.operate.vo.StockLotLockVO vo = new com.prolog.upcloud.base.wh.operate.vo.StockLotLockVO();
        List<String> orids=new ArrayList<>();
        for( String ids:dto.getIds()){
            orids.addAll(Arrays.asList(ids.split(",")));
        }
        vo.setIds(orids);
        vo.setStockStatus(dto.getIqcstatus());
        RestMessage stockrMsg= stockResource.unLockStockLot(vo);
        if(stockrMsg.isSuccess()==false){
            throw  new RuntimeException(stockrMsg.getMessage());
        }
        List<WmsInvStockLock> wmsInvStockLocks = new ArrayList<>();
        for(String stockid:dto.getIds()){
            WmsInvStockLock wmsInvStockLock = new WmsInvStockLock();
            wmsInvStockLock.setCreateby(userDTO.getId());
            wmsInvStockLock.setCreatedate(DateUtils.getNowDate());
            wmsInvStockLock.setStockaccno(stockid);
            wmsInvStockLock.setLockoper(InvLockConstant.LOCKOPER_UNLOCK);//解锁
            wmsInvStockLock.setUnlockres(dto.getIqcstatus());
            wmsInvStockLocks.add(wmsInvStockLock);
        }
        //如果解锁结论是合格

        List<WmsInvStockLot> invStockLotList = new ArrayList<>();
        RestMessage<List<WmsInvStockLot>> stockResourceStockListByIds= stockResource.getStockListByIds(orids.toArray(new String[orids.size()]));
        invStockLotList = stockResourceStockListByIds.getData();
        //如果解锁结论是待质检
        if (InvLockConstant.UNLOCKREASON_UNQUALIFIED.equals(dto.getIqcstatus()) ) {

            if(stockResourceStockListByIds.isSuccess()==false||stockResourceStockListByIds.getData().size()==0){
                throw new RuntimeException("没有找到需要处理库存！");
            }
            //待质检的解锁结论记录转入PC-锁定复检
            RestMessage gspRestMessage=  gspClient.addStockLockCheck(stockResourceStockListByIds.getData());
            if(gspRestMessage.isSuccess()==false){
                throw new RuntimeException(gspRestMessage.getMessage());
            }
        }

        //写入库存锁定记录表
        wmsInvStockLockMapper.saveBatch(wmsInvStockLocks);
       //解锁后需要通过接口回传ERP
        wmsInvStockLockToErp(invStockLotList,wmsInvStockLocks,"");

    }

}
