package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shkj.common.constant.RedisConstant;
import com.shkj.common.core.domain.Result;
import com.shkj.common.core.domain.entity.BaseConsignor;
import com.shkj.common.utils.DateUtils;
import com.shkj.wms.bo.*;
import com.shkj.wms.domain.BaseBarcodesIn;
import com.shkj.wms.domain.BaseDerive;
import com.shkj.wms.domain.BaseGoodsData;
import com.shkj.wms.mapper.BaseBarcodesInMapper;
import com.shkj.wms.service.*;
import com.shkj.wms.third.ykl.ThirdYklResult;
import com.shkj.wms.vo.BusinBillHeadVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 入库条码信息Service业务层处理
 *
 * @author zjx
 * @date 2023-03-29
 */
@Slf4j
@Service
public class BaseBarcodesInServiceImpl extends ServiceImpl<BaseBarcodesInMapper, BaseBarcodesIn> implements IBaseBarcodesInService {
    @Autowired
    private IBaseBarcodesInService iBaseBarcodesInService;

    @Autowired
    private IBaseGoodsDataService iBaseGoodsDataService;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    IBusinBillbodyService iBusinBillbodyService;
    @Autowired
    IBusinBillheadService iBusinBillheadService;

    @Autowired
    IBusinDataTaskService iBusinDataTaskService;

    @Autowired
    BaseBarcodesInMapper baseBarcodesInMapper;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> insertByAddBo(BaseBarcodesInAddBo bo) {
        LambdaQueryWrapper<BaseBarcodesIn> wrapper = new LambdaQueryWrapper<BaseBarcodesIn>().eq(BaseBarcodesIn::getQrCode, bo.getQrCode()).last("limit 1");
        BaseBarcodesIn one = getOne(wrapper);
        if (one != null) {
            return Result.err().msg("条码信息已存在");
        }
        BaseBarcodesIn baseBarcodesIn = BeanUtil.toBean(bo, BaseBarcodesIn.class);
        this.save(baseBarcodesIn);

        return Result.ok();
    }

    @Override
    public Result<Boolean> updateByEditBo(BaseBarcodesInEditBo bo) {
        return null;
    }

    @Override
    public List<BaseBarcodesIn> queryList(BaseBarcodesInQueryBo bo) {
        return null;
    }

    /**
     * 依柯力-同步返修信息
     *
     * @param bos 返修入库条码信息
     * @return 成功或失败信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ThirdYklResult thirdSyncRepairBarcodes(List<BaseBarcodesInThirdRepairBo> bos) {
        List<BaseBarcodesIn> barcodesInList = new ArrayList<>();
        List<String> barcodesList = new ArrayList<>();
        try {
            for (BaseBarcodesInThirdRepairBo bo : bos) {
                BaseBarcodesIn baseBarcodesIn = (BaseBarcodesIn) redisTemplate.opsForValue().get(RedisConstant.redisQrCode + bo.getQrCode());
                if (baseBarcodesIn == null) {
                    LambdaQueryWrapper<BaseBarcodesIn> wrapper = new LambdaQueryWrapper<BaseBarcodesIn>().eq(BaseBarcodesIn::getQrCode, bo.getQrCode()).last("limit 1");
                    baseBarcodesIn = getOne(wrapper);
                }
                if (baseBarcodesIn != null) {
                    baseBarcodesIn.setRepairTime(new Date());
                    baseBarcodesIn.setIsRepair("1");
                    barcodesInList.add(baseBarcodesIn);
                    barcodesList.add(baseBarcodesIn.getQrCode());
                }
            }
            if (!iBaseBarcodesInService.updateBatchById(barcodesInList)) {
                return ThirdYklResult.error("同步返修信息失败");
            }

            HashMap<String, Object> resultMap = new HashMap<>();
            resultMap.put("arr", barcodesList);
            return ThirdYklResult.ok("同步返修条码信息").put("data", resultMap);

        } catch (Exception e) {
            return ThirdYklResult.error(e.getMessage());
        }
    }

    /**
     * 依柯力-同步入库信息到wms
     *
     * @param bos 入库条码信息
     * @return 成功或失败信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ThirdYklResult thirdSyncBaseBarcodesIn(List<BaseBarcodesInThirdSyncBo> bos) {
        BaseBarcodesIn baseBarcodesIn = null;
        BaseGoodsData baseGoodsData = null;

        List<BaseBarcodesIn> inList = new ArrayList<>();
        List<BaseGoodsData> goodsDataList = new ArrayList<>();
        List<String> qrCodeList = new ArrayList<>();

        String goodsNo;
        List<String> goodnoList = new ArrayList<>();
        try {

            Result<BaseConsignor> result = iBaseGoodsDataService.getErpConsignorId();
            if (!Result.isOk(result)){
                log.info(result.getMsg());
            }
            //获取仓库ID
            BaseConsignor baseConsignor = result.getData();
            Long branchId = baseConsignor.getBranchId();

            for (BaseBarcodesInThirdSyncBo bo : bos) {
                //先从redis中读取数据，如果读取不到再从数据库中读取
                BaseBarcodesIn one = null;
                one = (BaseBarcodesIn) redisTemplate.opsForValue().get(RedisConstant.redisQrCode+bo.getQrCode()+branchId);
                if (one == null) {
                    LambdaQueryWrapper<BaseBarcodesIn> wrapper = new LambdaQueryWrapper<BaseBarcodesIn>()
                            .eq(BaseBarcodesIn::getQrCode, bo.getQrCode())
                            .eq(BaseBarcodesIn::getBranchId,branchId).last("limit 1");
                    one = getOne(wrapper);
                }
                if (one == null) {
                    qrCodeList.add(bo.getQrCode());
                    String isPunching = "0";
                    String isSplit = "0";
                    String punchingResult = "0";
                    if (bo.getIsPunching() == true) {
                        isPunching = "1";
                    }
                    if (bo.getIsSplit() == true) {
                        isSplit = "1";
                    }
                    if (bo.getPunchingResult() == true) {
                        punchingResult = "1";
                    }

                    baseBarcodesIn = BeanUtil.toBean(bo, BaseBarcodesIn.class);
                    baseBarcodesIn.setIsPunching(isPunching);
                    baseBarcodesIn.setIsSplit(isSplit);
                    baseBarcodesIn.setPunchingResult(punchingResult);
                    baseBarcodesIn.setInStatus("0");
                    baseBarcodesIn.setCreateTime(DateUtils.getNowDate());
                    baseBarcodesIn.setBranchId(branchId);
                    baseBarcodesIn.setIsRepair("0");

                    goodsNo = bo.getColor() + bo.getVehicheModel() + bo.getLocation() +isSplit + isPunching + bo.getOrientation()+bo.getLocationCode();
                    if (!goodnoList.contains(goodsNo)) {
                        BaseGoodsAddBo baseGoodsAddBo = new BaseGoodsAddBo();
                        goodnoList.add(goodsNo);
                        baseGoodsAddBo.setGoodsNo(goodsNo);
                        baseGoodsAddBo.setVehicheModel(bo.getVehicheModel());
                        baseGoodsAddBo.setGoodsName(bo.getQrCode().substring(0, 5));
                        baseGoodsAddBo.setColor(bo.getColor());
                        baseGoodsAddBo.setIsPunching(isPunching);
                        baseGoodsAddBo.setIsSplit(isSplit);
                        baseGoodsAddBo.setLocation(bo.getLocation());
                        baseGoodsAddBo.setLocationCode(bo.getLocationCode());
                        baseGoodsAddBo.setOrientation(bo.getOrientation());
                        baseGoodsAddBo.setGoodsAllValue(goodsNo);
                        baseGoodsAddBo.setBranchId(branchId);
                        baseGoodsData = BeanUtil.toBean(baseGoodsAddBo, BaseGoodsData.class);
                        goodsDataList.add(baseGoodsData);
                    }
                    baseBarcodesIn.setGoodsNo(goodsNo);
                    inList.add(baseBarcodesIn);
                }
            }

            //批量保存入库条码
            if (!this.saveBatch(inList)) {
                return ThirdYklResult.error("入库条码同步失败");
            } else {
                for (BaseBarcodesIn barcodesIn : inList) {
                    redisTemplate.opsForValue().set(RedisConstant.redisQrCode + barcodesIn.getQrCode()+branchId, barcodesIn);
                }
            }

            //保存产品信息
            for (BaseGoodsData goodsData : goodsDataList) {
                //判断产品是否已经存在，如果已经存在，则不再新增；先从redis中查找
                baseGoodsData = (BaseGoodsData) redisTemplate.opsForValue().get(RedisConstant.redisGoods + goodsData.getGoodsNo()+branchId);
                if (baseGoodsData == null) {
                    LambdaQueryWrapper<BaseGoodsData> wrapperBaseGoods = new LambdaQueryWrapper<BaseGoodsData>().eq(BaseGoodsData::getGoodsNo, goodsData.getGoodsNo()).last("limit 1");
                    baseGoodsData = iBaseGoodsDataService.getOne(wrapperBaseGoods);
                }
                if (baseGoodsData == null) {
                    iBaseGoodsDataService.save(goodsData);
                    redisTemplate.opsForValue().set(RedisConstant.redisGoods + goodsData.getGoodsNo()+branchId, goodsData);
                }
            }

            HashMap<Object, Object> arrResult = new HashMap<>(1);
            arrResult.put("arr", qrCodeList);
            return ThirdYklResult.ok().put("data", arrResult);
        } catch (Exception e) {
            return ThirdYklResult.error("入库条码同步失败:" + e.getMessage());
        }
    }


    /**
     * BCR扫码，根据条码查询
     *
     * @param qrCode 物料条码信息
     * @return 条码信息，此信息可继续传递给机械手
     */
    @Override
    public Result<BaseBarcodesIn> getBaseBarcodesInByQrCode(String qrCode) {
        try {
            //验证条码信息是否存在
            BaseBarcodesIn baseBarcodesIn = (BaseBarcodesIn) redisTemplate.opsForValue().get(RedisConstant.redisQrCode +qrCode);
            if (baseBarcodesIn == null) {
                LambdaQueryWrapper<BaseBarcodesIn> wrapper = new LambdaQueryWrapper<BaseBarcodesIn>().eq(BaseBarcodesIn::getQrCode, qrCode).last("limit 1");
                baseBarcodesIn = getOne(wrapper);
            }
            if (baseBarcodesIn == null) {
                return Result.err().msg("无此信息", qrCode);
            }
            //查询入库信息，是否已入库
            BusinBillHeadBodyQueryBo queryBo = new BusinBillHeadBodyQueryBo();
            queryBo.setQrCode(baseBarcodesIn.getQrCode());
            BusinBillHeadVo businBillHeadVo = iBusinBillheadService.queryBillHeadAndBody(queryBo);
            if (businBillHeadVo != null) {
                return Result.err().msg("此条码已入库", qrCode);
            }

            return Result.ok().data(baseBarcodesIn);

        } catch (Exception e) {
            return Result.err().msg(e.getMessage());
        }
    }

    @Override
    public BaseBarcodesIn getBaseBarcodesByQrCode(String qrCode) {
        BaseBarcodesIn baseBarcodesIn = (BaseBarcodesIn) redisTemplate.opsForValue().get(RedisConstant.redisQrCode +qrCode);
        if (baseBarcodesIn == null) {
            LambdaQueryWrapper<BaseBarcodesIn> wrapper = new LambdaQueryWrapper<BaseBarcodesIn>().eq(BaseBarcodesIn::getQrCode, qrCode).last("limit 1");
            baseBarcodesIn = getOne(wrapper);
        }
        return baseBarcodesIn;
    }

    /**
     * 根据派生信息查询条码信息
     *
     * @param bo 派生信息
     * @return 条码信息
     */
    @Override
    public BaseBarcodesIn getBaseBarcodesInByDerice(BaseDerive bo) {
        BaseBarcodesIn baseBarcodesIn = baseBarcodesInMapper.getBaseBarcodesInByDerice(bo);
        return baseBarcodesIn;
    }

    /**
     * 入库计划管理
     *
     * @param bo 条码信息
     * @return 条码信息
     */
    @Override
    public List<BaseBarcodesIn> getBillInPlanData(BaseBarcodesInQueryBo bo) {
       return baseBarcodesInMapper.getBillInPlanData(bo);
    }

}
