package com.shkj.wms.service.impl;


import cn.hutool.core.bean.BeanUtil;
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.utils.DateUtils;
import com.shkj.common.utils.uuid.UUID;
import com.shkj.wms.bo.*;
import com.shkj.wms.domain.*;
import com.shkj.wms.mapper.BaseBarcodesOutMapper;
import com.shkj.wms.mapper.BusinBillheadMapper;
import com.shkj.wms.service.*;
import com.shkj.wms.vo.BaseContainerVo;
import com.shkj.wms.vo.BusinBillHeadPlanOutVo;
import com.shkj.wms.vo.BusinBillHeadVo;
import com.shkj.wms.vo.BusinBillHeadbodyInVo;
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 javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 出入库单汇总Service业务层处理
 *
 * @author zjx
 * @date 2023-04-07
 */
@Slf4j
@Service
public class BusinBillheadServiceImpl extends ServiceImpl<BusinBillheadMapper, BusinBillhead> implements IBusinBillheadService {

    @Autowired
    IBusinBillbodyService iBusinBillbodyService;

    @Autowired
    IBaseDeriveService iBaseDeriveService;

    @Autowired
    IBaseBarcodesInService iBaseBarcodesInService;

    @Autowired
    IBusinDataTaskService iBusinDataTaskService;

    @Autowired
    IBaseGoodsDataService iBaseGoodsDataService;

    @Autowired
    IBaseContainerService iBaseContainerService;

    @Autowired
    BaseBarcodesOutMapper baseBarcodesOutMapper;

    @Autowired
    IBaseBarcodesOutService iBaseBarcodesOutService;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertBusinBillhead(BusinBillHeadAddBo bo) {
        BusinBillhead businBillhead = BeanUtil.toBean(bo, BusinBillhead.class);
        return this.save(businBillhead);
    }

    @Override
    public Boolean insertBusinBillhead(BusinBillhead billhead) {
        return this.baseMapper.insertBusinBillhead(billhead);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinBillHeadVo queryBillHeadAndBody(BusinBillHeadBodyQueryBo bo) {
        return this.baseMapper.queryBillHeadAndBody(bo);
    }

    @Override
    public BusinBillhead getBusinBillHeadByTraverseDate(Date traverseDate) {
        return this.baseMapper.selectBusinBillHeadByTraverseDate(traverseDate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> saveBillTaskIn(BillTaskAddbo billTaskAddbo) {

        String isRepair = billTaskAddbo.getIsRepair();
        List<BasinBarcodeInAddBo> baseBarcodesIns = billTaskAddbo.getBarcodesList();
        int lindId = 0;
        List<BusinBillbody> bodyList = new ArrayList<>();
        List<BusinDataTask> taskList = new ArrayList<>();
        BusinBillHeadAddBo billhead = null;
        String transId = UUID.randomUUID().toString();

        for (BasinBarcodeInAddBo barcodesIn : baseBarcodesIns) {
            //查询物料是否已经入库
            BusinBillHeadBodyQueryBo queryBo = new BusinBillHeadBodyQueryBo();
            queryBo.setQrCode(barcodesIn.getQrCode());
            BusinBillHeadVo businBillHeadVo = this.queryBillHeadAndBody(queryBo);
            if (businBillHeadVo != null) {
                return Result.err().msg("此 " + barcodesIn.getQrCode() + "条码已入库");
            }

            //入库明细
            lindId++;
            String goodsNo = barcodesIn.getColor() + barcodesIn.getVehicheModel() + barcodesIn.getLocation() + barcodesIn.getIsSplit() + barcodesIn.getIsPunching() + barcodesIn.getOrientation()+barcodesIn.getLocationCode();
            //获取产品信息
            BaseGoodsData goodsData = iBaseGoodsDataService.getBaseGoodsByBarcodes(goodsNo);
            if (null == goodsData) {
                return Result.err().msg("此条码" + barcodesIn.getQrCode() + "未找到产品信息");
            }

            //任务信息
            BusinTaskAddBo taskAddBo = new BusinTaskAddBo();
            String taskCode = UUID.randomUUID().toString();
           //taskAddBo.setTaskCode(taskCode);
            taskAddBo.setGoodsNo(goodsData.getGoodsNo());
            taskAddBo.setQrCode(barcodesIn.getQrCode());
            taskAddBo.setTaskStatus("0");
            taskAddBo.setContainerId(billTaskAddbo.getContainerCode());
            taskAddBo.setBatch(DateUtils.dateTimeNow("yyyy-MM-dd"));
            taskAddBo.setIsUrgent("0");
            taskAddBo.setIsTop("0");

            //手工入库 动态传值
            taskAddBo.setTaskType("7");
            taskAddBo.setTaskStarttime(DateUtils.getNowDate());
            taskAddBo.setCreateTime(DateUtils.getNowDate());
            BusinDataTask businDataTask = BeanUtil.toBean(taskAddBo, BusinDataTask.class);
            taskList.add(businDataTask);


            //入库异常时，不生成入库单，只生成入库任务
            if (!"1".equals(isRepair)) {
                BusinBillbody body = new BusinBillbody();
                body.setLineId(lindId);
                body.setGoodsNo(goodsData.getGoodsNo());
                body.setQty(1);
               // body.setTransId(0);
                //body.setTaskCode(taskCode);
                bodyList.add(body);
            }
        }

        if (!"1".equals(isRepair)) {
            Long tqty = Long.valueOf(baseBarcodesIns.size());

            //生成入库信息
            billhead = new BusinBillHeadAddBo();
            billhead.setTransId(transId);
            //1入库 2出库 3退回
            billhead.setTransNo("1");
            //1入库 -1 出库
            billhead.setTransQual("1");
            billhead.setTqty(tqty);
            billhead.setContainerCode(billTaskAddbo.getContainerCode());
        }

        if (!iBusinDataTaskService.saveBatch(taskList)) {
            return Result.err().msg("保存入库任务失败");
        }
        if (bodyList.size() > 0) {
            if (!iBusinBillbodyService.saveBatch(bodyList)) {
                return Result.err().msg("保存入库单明细失败");
            }
        }
        if (billhead != null) {
            if (!this.insertBusinBillhead(billhead)) {
                return Result.err().msg("保存入库单汇总失败");
            }
        }

        if (!iBaseContainerService.updateById(billTaskAddbo.getContainerCode())) {
            return Result.err().msg("更新治具占用状态失败");
        }

        return Result.ok();
    }

    @Override
    public List<BusinBillHeadPlanOutVo> getBillHeadBodyPlanOut(BaseBarcodesOutQueryBo bo) {
        return  this.baseMapper.selectBillHeadBodyPlanOut(bo);
    }

    @Override
    public List<BusinBillHeadbodyInVo> getBillHeadBodyInOutData(BusinBillHeadBodyQueryBo bo) {
        return this.baseMapper.selectBillHeadBodyInOutData(bo);
    }


    @Override
    public Result<Boolean> saveBillHeadBodyOut(List<BaseBarcodesOutAddBo> bos) {


        List<BusinBillbody> bodyList = new ArrayList<>();
        List<BusinBillhead> headList = new ArrayList<>();
        List<BusinDataTask> taskList = new ArrayList<>();
        List<BaseBarcodesOut> barcodesOutList = new ArrayList<>();
        for (BaseBarcodesOutAddBo baseBarcodesOutAddBo : bos) {
            BaseBarcodesOut baseBarcodesOut = (BaseBarcodesOut) redisTemplate.opsForValue().get(RedisConstant.redisVin + baseBarcodesOutAddBo.getVin());
            //回填出库队列的状态
            baseBarcodesOut.setOutStatus("1");

            String transId = "O_"+DateUtils.getNowDate();
            //根据出库中的车型代码，派生查找派生表中的保险杠信息
            List<BaseDerive> baseDeriveList = iBaseDeriveService.getBaseDeriveListByVehiche(baseBarcodesOutAddBo);
            if (baseDeriveList.size() == 0) {
                //return ThirdYklResult.error("根据派生未找到保险杠信息");
                //记录查找不到的派生信息
            }
            int lindId = 0;
            int tqty = 0;
            for (BaseDerive baseDerive : baseDeriveList) {
                //一个VIN号对用多个物料号，前后杠或后杠分体
                lindId += 1;
                //根据派生信息查找条码及物料信息
                BaseBarcodesIn baseBarcodesIn = iBaseBarcodesInService.getBaseBarcodesInByDerice(baseDerive);

                //生成作业任务
                BusinDataTask task = new BusinDataTask();
                String taskCode = UUID.randomUUID().toString();
                task.setTaskCode(taskCode);
                task.setTaskType("4");//任务类型 0 正常入库 1维修异常 2扫码异常  3入库冲孔 4 正常出库 5紧急出库 6越库出库
                task.setBatch(DateUtils.dateTime(baseBarcodesOutAddBo.getTraverseDate()));
                task.setPriority("2");
                task.setIsTop("0");

                task.setIsUrgent(baseBarcodesOutAddBo.getIsUrgent());
                task.setCreateTime(DateUtils.getNowDate());
                task.setTraverseDate(baseBarcodesOutAddBo.getTraverseDate());//过点时间
                taskList.add(task);
                barcodesOutList.add(baseBarcodesOut);
            }

            BusinBillhead head = new BusinBillhead();
            head.setTransId(transId);
            head.setTransNo("2");//1入库 2出库 3退回
            head.setTransQual("-1"); //1入库 -1 出库
            head.setTqty(tqty); //保险杠总数量
            head.setVin(baseBarcodesOutAddBo.getVin());
            head.setTraverseDate(baseBarcodesOutAddBo.getTraverseDate());
            head.setBatch(DateUtils.getDate());
            headList.add(head);
        }

        if (!this.saveBatch(headList)) {
            return Result.err().msg("保存出库单汇总表失败");
        }

        if (!iBusinBillbodyService.saveBatch(bodyList)) {
            return Result.err().msg("保存出库单明细表失败");
        }
        if (!iBusinDataTaskService.saveBatch(taskList)) {
            return Result.err().msg("保存作业任务失败");
        }

        if(!iBaseBarcodesOutService.saveBatch(barcodesOutList)){
            return Result.err().msg("回填车辆队列信息失败");
        }

        return Result.ok();
    }

}
