package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.shkj.common.core.domain.Result;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.wms.bo.*;
import com.shkj.wms.domain.*;
import com.shkj.wms.enums.BusinTaskTypeEnum;
import com.shkj.wms.enums.TaskStatusEnum;
import com.shkj.wms.mapper.SysStockDetailMapper;
import com.shkj.wms.service.*;
import com.shkj.wms.vo.BaseLocationVo;
import com.shkj.wms.vo.SysStockDetailVo;
import lombok.extern.slf4j.Slf4j;
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.*;
import java.util.stream.Collectors;

/**
 * 库存明细Service业务层处理
 *
 * @author lch
 * @date 2023-05-05
 */
@Slf4j
@Service
public class SysStockDetailServiceImpl extends ServiceImpl<SysStockDetailMapper, SysStockDetail> implements ISysStockDetailService {
    @Autowired
    private IBaseLocationService iBaseLocationService;

    @Autowired
    private ISysStockDetailQrcodeService iSysStockDetailQrcodeService;

    @Autowired
    private IBaseGoodsDataService iBaseGoodsDataService;

    @Autowired
    private IBusinDataTaskService iBusinDataTaskService;
    @Autowired
    private BaseBarcodesOutServiceImpl baseBarcodesOutService;
    @Autowired
    private IBaseBarcodesInService iBaseBarcodesInService;
    @Resource
    private IBaseDeriveService iBaseDeriveService;
    @Autowired
    private IBaseLogicareaVmService iBaseLogicareaVmService;
    @Autowired
    private SysStockDetailMapper sysStockDetailMapper;

    @Override
    public Result<SysStockDetailVo> queryById(Long id) {
        SysStockDetail db = this.baseMapper.selectById(id);
        SysStockDetailVo vo = BeanUtil.toBean(db, SysStockDetailVo.class);
        return Result.ok().data(vo);
    }


    @Override
    public Result<List<SysStockDetailVo>> queryByLocation(Long locationId) {
        SysStockDetailQueryBo bo = new SysStockDetailQueryBo();
        bo.setLocationId(locationId);
        List<SysStockDetailVo> detailVos = this.queryList(bo);
        if (detailVos.size() > 0) {
            return Result.ok().data(detailVos);
        } else {
            return Result.err();
        }
    }

    @Override
    public List<SysStockDetailVo> queryList(SysStockDetailQueryBo bo) {
        LambdaQueryWrapper<SysStockDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getConsignorId() != null, SysStockDetail::getConsignorId, bo.getConsignorId());
        lqw.eq(bo.getBranchId() != null, SysStockDetail::getBranchId, bo.getBranchId());
        lqw.eq(bo.getStorageId() != null, SysStockDetail::getStorageId, bo.getStorageId());
        lqw.eq(bo.getAreaId() != null, SysStockDetail::getAreaId, bo.getAreaId());
        lqw.eq(StrUtil.isNotBlank(bo.getTunnel()), SysStockDetail::getTunnel, bo.getTunnel());
        lqw.eq(bo.getContainerCode() != null, SysStockDetail::getContainerCode, bo.getContainerCode());
        lqw.eq(bo.getQty() != null, SysStockDetail::getQty, bo.getQty());
        lqw.eq(bo.getLocationId() != null, SysStockDetail::getLocationId, bo.getLocationId());
        lqw.eq(StrUtil.isNotBlank(bo.getBatch()), SysStockDetail::getBatch, bo.getBatch());
        lqw.eq(StrUtil.isNotBlank(bo.getIsPuch()), SysStockDetail::getIsPuch, bo.getIsPuch());
        lqw.eq(bo.getInTime() != null, SysStockDetail::getInTime, bo.getInTime());
        lqw.eq(bo.getOutTime() != null, SysStockDetail::getOutTime, bo.getOutTime());
        List<SysStockDetailVo> voList = entity2Vo(this.list(lqw));
        return voList;

    }
    @Override
    public List<SysStockDetail> selectsystock(List<String> goods,Long locationid){
        return baseMapper.selectsystock(goods, locationid);
    }

    @Override
    public boolean deleteBySysStockByLocationId(Long locationId) {
        sysStockDetailMapper.deleteBySysStockByLocationId(locationId);
        return true;
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<SysStockDetailVo> entity2Vo(Collection<SysStockDetail> collection) {
        List<SysStockDetailVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, SysStockDetailVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<SysStockDetail> page = (Page<SysStockDetail>) collection;
            Page<SysStockDetailVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> insertByAddBo(SysStockDetailAddBo bo) {
        SysStockDetail add = BeanUtil.toBean(bo, SysStockDetail.class);
        this.save(add);
        return Result.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> updateByEditBo(SysStockDetailEditBo bo) {
        SysStockDetail one = getById(bo.getId());
        if (one == null) {
            return Result.err().msg("不存在");
        }
        SysStockDetail update = BeanUtil.toBean(bo, SysStockDetail.class);
        this.updateById(update);
        return Result.ok();
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> deleteWithValidById(List<Long> ids, Boolean isValid) {
        LambdaQueryWrapper<SysStockDetail> wrapper = new LambdaQueryWrapper<SysStockDetail>().in(SysStockDetail::getId, ids)
                .eq(SysStockDetail::getBranchId, SecurityUtils.getCurrentBranchId());
        this.remove(wrapper);
        return Result.ok();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> productDepositDetail(Long locationId, Long containerId, String batch, String isPuch, List<Map<String, String>> goods,Long storageCode) {

        //获取库位上是否有物料信息
        SysStockDetailQueryBo stockDetailQueryBo = new SysStockDetailQueryBo();
        stockDetailQueryBo.setLocationId(locationId);
        List<SysStockDetailVo> sysStockDetailVos = this.queryList(stockDetailQueryBo);
//        if (sysStockDetailVos.size() > 0) {
//            return Result.err().msg("该货位已存在库存信息！");
//        } else {
            for (Map<String, String> good : goods) {
                Result<BaseLocationVo> baseLocationVoResult = iBaseLocationService.queryById(locationId);
                BaseLocationVo locationVo = baseLocationVoResult.getData();
                SysStockDetail sysStockDetail = new SysStockDetail();
                sysStockDetail.setBranchId(locationVo.getBranchId());
                sysStockDetail.setStorageId(storageCode);
                sysStockDetail.setAreaId(locationVo.getAreaId());
                sysStockDetail.setTunnel(locationVo.getTunnel());
                sysStockDetail.setContainerCode(containerId);
                sysStockDetail.setQty(BigDecimal.valueOf(1));
                sysStockDetail.setLocationId(locationId);
                sysStockDetail.setBatch(batch);
                sysStockDetail.setIsPuch(isPuch);
                if (StrUtil.isNotBlank(good.get("goodsNo"))) {
                    sysStockDetail.setGoodsNo(good.get("goodsNo"));
                }
                if (StrUtil.isNotBlank(good.get("qrCode"))) {
                    sysStockDetail.setQrCode(good.get("qrCode"));
                }
                this.baseMapper.insert(sysStockDetail);
                String status = "1";
//                if ("1".equals(isPuch)) {
//                    status = "3";
//                }
                //更新库位状态
                iBaseLocationService.changeLocationStatus(locationId, status);

                iSysStockDetailQrcodeService.depositGoods(sysStockDetail.getId(), good);
            }
//
//            //待补货区和缓冲区货位回填逻辑区域 (不影响正常存储区)
//            String qrCode = goods.get(0).get("qrCode");
//            BaseBarcodesIn barcodesByQrCode = iBaseBarcodesInService.getBaseBarcodesByQrCode(qrCode);
//            String color= barcodesByQrCode.getColor();
//            String vehicheModel = barcodesByQrCode.getVehicheModel();
//            //获取派生
//            BaseDeriveQueryBo deriveQueryBo = new BaseDeriveQueryBo();
//            deriveQueryBo.setVehicheModel(vehicheModel);
//            deriveQueryBo.setColor(color);
//            BaseDerive derive = iBaseDeriveService.getBaseDeriveBybarcodes(deriveQueryBo);
//            Long deriveId = derive.getId();
//            //根据派生拿到逻辑区域并回写道对应货位
//            BaseLogicAreaDerive logicAreaDerive = iBaseLogicareaVmService.getOne(new LambdaQueryWrapper<BaseLogicAreaDerive>()
//                    .eq(BaseLogicAreaDerive::getDeriveId, deriveId)
//                    .last("limit 1"));
//            BaseLocation location = iBaseLocationService.getById(locationId);
//            if ("19".equals(location.getAreaId())||"18".equals(location.getAreaId())) {
//                location.setLogicId(logicAreaDerive.getLogicareaId());
//            }
//            location.setLocationStatus("1");
//            iBaseLocationService.updateById(location);

//        }
        return Result.ok();
    }

    @Override
    public Result<Boolean> reduceInventoryDetail(Long branchId, Long locationId, Long storageId, Long areaId, List<Map<String, String>> goods) {
        return null;
    }

    @Override
    public List<SysStockDetailVo> StockInquiry(SysStockDetailQueryBo bo) {
        return this.baseMapper.StockInquiry(bo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> updateStock(BaseGoodsData goodsData, String id) {
        List<BaseGoodsData> baseGoodsDataList = iBaseGoodsDataService.getbaseGooddata(goodsData);
        BaseGoodsData baseGoodsData = new BaseGoodsData();
        if (baseGoodsDataList.size()<=0){
            return Result.err().msg("当前数据不存在");
        }
        baseGoodsData = baseGoodsDataList.get(0);

        SysStockDetail stockDetail = this.getById(id);

        stockDetail.setGoodsNo(baseGoodsData.getGoodsNo());

        this.updateById(stockDetail);

        return Result.ok();
    }

    @Override
    @Transactional(rollbackFor =  Exception.class)
    public Result<Boolean> removeLocation(String oldLocation, String newLoaction,  String id,String newid) {
        BaseLocationQueryBo oldbaseLocationBo =new BaseLocationQueryBo();
        BaseLocationQueryBo newbaseLocationBo = new BaseLocationQueryBo();
        oldbaseLocationBo.setId(Long.valueOf(oldLocation));
        newbaseLocationBo.setId(Long.valueOf(newLoaction));

        BaseLocationVo oldbaseLocationVo = iBaseLocationService.queryList(oldbaseLocationBo).get(0);
        BaseLocationVo newbaseLocationVo = iBaseLocationService.queryList(newbaseLocationBo).get(0);


        //创建任务
        BusinDataTask businDataTask =new BusinDataTask();
        businDataTask.setTaskType(BusinTaskTypeEnum.remove.getValue());
        businDataTask.setFromRow(oldbaseLocationVo.getLocationRow());
        businDataTask.setFromColumn(String.valueOf(oldbaseLocationVo.getLocationColumn()));
        businDataTask.setFromLayer(oldbaseLocationVo.getLayer());
        businDataTask.setToRow(newbaseLocationVo.getLocationRow());
        businDataTask.setToColumn(String.valueOf(newbaseLocationVo.getLocationColumn()));
        businDataTask.setToLayer(newbaseLocationVo.getLayer());
        businDataTask.setTaskStatus(TaskStatusEnum.wait_put.getValue());
        iBusinDataTaskService.insertBusinTask(businDataTask);

        BaseLocation oldbaseLocation = BeanUtil.toBean(oldbaseLocationVo,BaseLocation.class);
        BaseLocation newbaseLocation = BeanUtil.toBean(newbaseLocationVo,BaseLocation.class);
        //新老货位状态互换
        oldbaseLocation.setLocationStatus(newbaseLocationVo.getLocationStatus());
        newbaseLocation.setLocationStatus(oldbaseLocationVo.getLocationStatus());
        iBaseLocationService.updateById(oldbaseLocation);
        iBaseLocationService.updateById(newbaseLocation);
        //更新库存明细表货位id,仓库id,货区id
        SysStockDetail stockDetail = this.getById(id);
//        SysStockDetail newstockDetail = this.getById(newid);
//        newstockDetail.setLocationId(stockDetail.getLocationId());
//        newstockDetail.setBranchId(stockDetail.getBranchId());
//        newstockDetail.setAreaId(stockDetail.getAreaId());
        stockDetail.setLocationId(Long.valueOf(newbaseLocation.getId()));
        stockDetail.setBranchId(newbaseLocation.getBranchId());
        stockDetail.setAreaId(newbaseLocation.getAreaId());
        this.updateById(stockDetail);
//        this.updateById(newstockDetail);

        return Result.ok();
    }


    @Override
    public List<SysStockDetailVo> getLocation(List<String> goodsnoList){
        return this.baseMapper.getLocation(goodsnoList);
    }
    /**
     * 整理出需要在一条任务处理的分体三个产品
     */
    @Override
    public Map<String,List<String>> getLocationneaten(List<SysStockDetailVo> SysStockDetailVo) {


        List<String> locationidList = SysStockDetailVo.stream().map(e -> String.valueOf(e.getLocationId())).collect(Collectors.toList());
        List<String> globalityData = baseBarcodesOutService.getGlobalityData(locationidList);
        Map<String,List<String>> goodsnolocationmap=new HashMap<>();
        for (String s :
                globalityData) {
            List<String> goodsList =new ArrayList<>();
            SysStockDetailVo.stream().forEach(e-> {
                e.getLocationId().equals(s);
                goodsList.add(e.getGoodsNo());
            });
        goodsnolocationmap.put(s,goodsList);
        }
        return goodsnolocationmap;
    }




}

