package com.sy.coinage.workshop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.sy.coinage.core.exception.RetException;
import com.sy.coinage.workshop.dao.BaseInfoDao;
import org.springframework.stereotype.Service;

import com.sy.coinage.workshop.dao.StockDao;
import com.sy.coinage.workshop.model.*;
import com.sy.coinage.workshop.service.IStockService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * -实时库存表ServiceImpl
 */
@Service
public class StockServiceImpl extends ServiceImpl<StockDao, Stock> implements IStockService {

    @Resource
    private BaseInfoDao baseInfoDao;

    @Override
    public Stock getStock(Integer securitiesId, Integer wareId, Integer areaId) {
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getSecuritiesId, securitiesId).eq(Stock::getWareId, wareId).eq(Stock::getAreaId, areaId);
        return this.getOne(queryWrapper);
    }

    @Override
    public void stockSub(Integer securitiesId, String securities, Integer areaId, Integer wareId, String wareCn, Integer racketNum, Integer boxNum, Integer piecesTotal, Integer checkBox) {
        Stock stock = this.getStock(securitiesId, wareId, areaId);
        if (stock == null) {
            stock = new Stock();
            stock.setWareId(wareId);
            stock.setWareCn(wareCn);
            // FIXME 库位id
            stock.setAreaId(areaId);
            stock.setSecuritiesId(securitiesId);
            stock.setSecurities(securities);
            stock.setRacketNum(0);
            stock.setBoxNum(0);
            stock.setPiecesTotal(0);
            stock.setCheckBoxNum(0);
        }
        if (racketNum != null && racketNum > 0) {
            stock.setRacketNum(stock.getRacketNum() - racketNum);
        }
        if (boxNum != null && boxNum > 0) {
            stock.setBoxNum(stock.getBoxNum() - boxNum);
        }
        if (piecesTotal != null && piecesTotal > 0) {
            stock.setPiecesTotal(stock.getPiecesTotal() - piecesTotal);
        }
        if (checkBox != null && checkBox > 0) {
            stock.setCheckBoxNum(stock.getCheckBoxNum() - checkBox);
        }
        if (stock.getId() != null && stock.getId() > 0) {
            this.updateById(stock);
        } else {
            this.save(stock);
        }
    }

    @Override
    @Transactional
    public void stockAdd(Integer securitiesId, String securities, Integer areaId, Integer wareId, String wareCn, Integer racketNum, Integer boxNum, Integer piecesTotal, Integer checkBox) {
        Stock stock = this.getStock(securitiesId, wareId, areaId);
        if (stock == null) {
            stock = new Stock();
            stock.setWareId(wareId);
            stock.setWareCn(wareCn);
            // FIXME 库位id
            stock.setAreaId(areaId);
            stock.setSecuritiesId(securitiesId);
            stock.setSecurities(securities);
            stock.setRacketNum(0);
            stock.setBoxNum(0);
            stock.setPiecesTotal(0);
            stock.setCheckBoxNum(0);
        }
        if (racketNum != null && racketNum > 0) {
            stock.setRacketNum(stock.getRacketNum() + racketNum);
        }
        if (boxNum != null && boxNum > 0) {
            stock.setBoxNum(stock.getBoxNum() + boxNum);
        }
        if (piecesTotal != null && piecesTotal > 0) {
            stock.setPiecesTotal(stock.getPiecesTotal() + piecesTotal);
        }
        if (checkBox != null && checkBox > 0) {
            stock.setCheckBoxNum(stock.getCheckBoxNum() + checkBox);
        }
        if (stock.getId() != null && stock.getId() > 0) {
            this.updateById(stock);
        } else {
            this.save(stock);
        }
    }

    @Override
    public List<Stock> getStockList(Integer wareId, Integer securitiesId) {
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getWareId, wareId);
        queryWrapper.eq(Stock::getSecuritiesId, securitiesId);
        return this.list(queryWrapper);
    }

    @Override
    public Integer getEliminateStockTotal(Integer wareId, Integer securitiesId, Product product) {
        Integer total = 0;
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getWareId, wareId);
        queryWrapper.eq(Stock::getSecuritiesId, securitiesId);
        queryWrapper.eq(Stock::getAreaId, 2);
        Stock model = this.getOne(queryWrapper);
        if (model != null) {
            List<BaseInfo> baseInfos = this.baseList(wareId, 2, securitiesId);
            if (baseInfos != null && baseInfos.size() > 0) {
                for (BaseInfo info : baseInfos) {
                    total = total + info.getQty() * product.getAmountPerBox();
                }
            }
            total = total + model.getBoxNum() * product.getAmountPerBox() + model.getPiecesTotal();
        }
        return total;
    }

    @Override
    public Integer getProductStockTotal(Integer wareId, Integer securitiesId, Product product) {
        Integer total = 0;
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getWareId, wareId);
        queryWrapper.eq(Stock::getSecuritiesId, securitiesId);
        queryWrapper.eq(Stock::getAreaId, 1);
        Stock model = this.getOne(queryWrapper);
        if (model != null) {
            List<BaseInfo> baseInfos = this.baseList(wareId, 1, securitiesId);
            if (baseInfos != null && baseInfos.size() > 0) {
                for (BaseInfo info : baseInfos) {
                    total = total + info.getQty() * product.getAmountPerBox();
                }
            }
            total = total + model.getBoxNum() * product.getAmountPerBox() + model.getPiecesTotal();
        }
        return total;
    }

    @Override
    public Stock getLastStock(Integer wareId) {
        LambdaQueryWrapper<Stock> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Stock::getWareId, wareId);
        Page<Stock> page = new Page<>(1, 1);
        IPage<Stock> resp = this.page(page, queryWrapper);
        if (resp.getRecords() == null || resp.getRecords().size() == 0) {
            throw new RetException("库存信息不存在");
        }
        return resp.getRecords().get(0);
    }

    /**
     * 查询剔除品库的所包含拍子
     *
     * @param wareId
     * @param areaId
     * @param securitiesId
     * @return
     */
    private List<BaseInfo> baseList(Integer wareId, Integer areaId, Integer securitiesId) {
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getLocWareId, wareId);
        queryWrapper.eq(BaseInfo::getLocAreaId, areaId);
        queryWrapper.eq(BaseInfo::getSecuritiesId, securitiesId);
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库  5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返捡总库出库 10:返捡车间确认 11拆包 12：已发货 13:返回机台
        queryWrapper.and(wq -> { // 入库的可以是初始的 返检的 13:返回机台
            wq.eq(BaseInfo::getStatus, 2).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
        });
        List<BaseInfo> resp = this.baseInfoDao.selectList(queryWrapper);
        return resp;
    }

}
