/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.warehouse.storage.service;

import java.math.BigDecimal;
import java.util.*;

import com.jeeplus.modules.warehouse.goods.entity.Goods;
import com.jeeplus.modules.warehouse.goods.entity.GoodsInfo;
import com.jeeplus.modules.warehouse.goods.mapper.GoodsInfoMapper;
import com.jeeplus.modules.warehouse.goods.mapper.GoodsMapper;
import com.jeeplus.modules.warehouse.ikanalyzer.IKSegmenter;
import com.jeeplus.modules.warehouse.ledger.dto.CountLedgerInfo;
import com.jeeplus.modules.warehouse.qrcode.entity.QrCode;
import com.jeeplus.modules.warehouse.qrcode.mapper.QrCodeMapper;
import com.jeeplus.modules.warehouse.shelves.entity.Shelves;
import com.jeeplus.modules.warehouse.shelves.mapper.ShelvesMapper;
import com.jeeplus.modules.warehouse.shelves.utils.ShelvesUtil;
import com.jeeplus.modules.warehouse.storage.dto.CountStorageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jeeplus.core.persistence.Page;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.warehouse.storage.entity.Storage;
import com.jeeplus.modules.warehouse.storage.mapper.StorageMapper;
import com.jeeplus.modules.warehouse.storage.entity.StorageInfo;
import com.jeeplus.modules.warehouse.storage.mapper.StorageInfoMapper;

/**
 * 入库信息Service
 * @author huyi
 * @version 2023-02-13
 */
@Service
@Transactional(readOnly = true)
public class StorageService extends CrudService<StorageMapper, Storage> {

	@Autowired
	private StorageInfoMapper storageInfoMapper;
	@Autowired
	private GoodsInfoMapper goodsInfoMapper;
	@Autowired
	private QrCodeMapper qrCodeMapper;
	@Autowired
	private ShelvesMapper shelvesMapper;
	@Autowired
	private GoodsMapper goodsMapper;

	
	public Storage get(String id) {
		Storage storage = super.get(id);
		List<StorageInfo> storageInfoList = storageInfoMapper.findList(new StorageInfo(storage));
		storage.setStorageInfoList(storageInfoList);
		return storage;
	}

	public Storage countStorage(String id) {
		Storage storage = super.get(id);
		List<CountStorageInfo> countStorageInfoList = storageInfoMapper.findCsiList(new StorageInfo(storage));
		Map<String, List<CountStorageInfo>> map = new HashMap<>();
		for (CountStorageInfo countStorageInfo : countStorageInfoList) {
			String goodsInfoId = countStorageInfo.getGoodsInfo().getId();
			List<CountStorageInfo> list = map.get(goodsInfoId);
			if (null == list) {
				list = new ArrayList<>();
				list.add(countStorageInfo);
				map.put(countStorageInfo.getGoodsInfo().getId(), list);
			} else {
				list.add(countStorageInfo);
			}
		}

		List<CountStorageInfo> csiList = new ArrayList<>();
		for (Map.Entry<String, List<CountStorageInfo>> entry : map.entrySet()) {
			List<CountStorageInfo> list = entry.getValue();
			CountStorageInfo csi = new CountStorageInfo();
			Set<String> wNameSet = new HashSet<>();
			String shelvesNames = "";
			int num = 0;
			BigDecimal sum = new BigDecimal(0);
			for (int i = 0; i < list.size(); i ++) {
				CountStorageInfo c = list.get(0);
				if (i == 0) {
					csi.setGoodsInfo(c.getGoodsInfo());
					csi.setModel(c.getModel());
					csi.setName(c.getName());
					csi.setType(c.getType());
					csi.setState(c.getState());
                    csi.setAmount(c.getAmount());
				}
				if (i != list.size() - 1) {
					shelvesNames = shelvesNames + c.getShelves().getName() + ",";
				} else {
					shelvesNames = shelvesNames + c.getShelves().getName();
				}
				wNameSet.add(c.getWarehouse().getName());
				num += c.getNum();
				sum = sum.add(c.getSum());
			}
			String wNames = ShelvesUtil.mergerWarehouseName(wNameSet);
			csi.setShelvesNames(shelvesNames);
			csi.setWarehouseNames(wNames);
			csi.setNum(num);
			csi.setSum(sum);
			csiList.add(csi);
		}

		storage.setCountStorageInfoList(csiList);
		return storage;
	}

	/**
	 * 根据统计信息查询入库明细
	 * @param countStorageInfo
	 * @return
	 */
	public List<StorageInfo> findInfoBycountStorage(CountStorageInfo countStorageInfo) {
		StorageInfo storageInfo = new StorageInfo();
		storageInfo.setShelves(countStorageInfo.getShelves());
		storageInfo.setGoodsInfo(countStorageInfo.getGoodsInfo());
		storageInfo.setPage(countStorageInfo.getPage());
		return storageInfoMapper.findList(storageInfo);
	}

	public List<Storage> findList(Storage storage) {
		return super.findList(storage);
	}
	
	public Page<Storage> findPage(Page<Storage> page, Storage storage) {
		return super.findPage(page, storage);
	}
	
	@Transactional(readOnly = false)
	public void save(Storage storage) {
		super.save(storage);
		Map<String, Integer> map = new HashMap<>();
		BigDecimal money = new BigDecimal(0.00);
		for (StorageInfo storageInfo : storage.getStorageInfoList()){
			if (storageInfo.getId() == null){
				continue;
			}
			GoodsInfo goodsInfo = storageInfo.getGoodsInfo();
			if (StorageInfo.DEL_FLAG_NORMAL.equals(storageInfo.getDelFlag())){
				if (StringUtils.isBlank(storageInfo.getId())){
					storageInfo.setStorage(storage);
					storageInfo.preInsert();
					storageInfoMapper.insert(storageInfo);

					// 计算需要变更的总价格
					money = money.subtract(goodsInfo.getAmount());
					// 计算货品明细中的需要变更的数量
					Integer count = map.get(goodsInfo.getId());
					if (null == count) {
						count = -1;
					} else {
						count --;
					}
					map.put(goodsInfo.getId(), count);

					// 更改二维码状态为已入库
					QrCode qrCode = qrCodeMapper.get(storageInfo.getQrCode().getId());
					qrCode.setState("1");
					qrCode.preUpdate();
					qrCodeMapper.update(qrCode);
				}else{
					storageInfo.preUpdate();
					storageInfoMapper.update(storageInfo);
				}
			}else{
				storageInfoMapper.delete(storageInfo);
				money = money.add(goodsInfo.getAmount());
				// 计算货品明细中的需要变更的数量
				Integer count = map.get(goodsInfo.getId());
				if (null == count) {
					count = 1;
				} else {
					count ++;
				}
				map.put(goodsInfo.getId(), count);

				// 更改二维码状态为未入库
				QrCode qrCode = qrCodeMapper.get(storageInfo.getQrCode().getId());
				qrCode.setState("0");
				qrCode.preUpdate();
				qrCodeMapper.update(qrCode);
			}
		}

		// 更新货品明细中的数量
		Set<Map.Entry<String, Integer>> countSet = map.entrySet();
		for (Map.Entry<String, Integer> entry : countSet) {
			String goodsInfoId = entry.getKey();
			int count = entry.getValue();
			GoodsInfo goodsInfo = goodsInfoMapper.get(goodsInfoId);
			goodsInfo.setNum(goodsInfo.getNum() + count);
			goodsInfo.preUpdate();
			goodsInfoMapper.update(goodsInfo);
		}

		// 更新货品表总价
		Goods temGoods = new Goods();
		temGoods.setBatchNum(storage.getBatchNum());
		Goods goods = goodsMapper.findByPc(temGoods);
		goods.setSum(goods.getSum().add(money));
		goods.preUpdate();
		goodsMapper.update(goods);
	}
	
	@Transactional(readOnly = false)
	public void delete(Storage storage) {
		super.delete(storage);
		storageInfoMapper.delete(new StorageInfo(storage));
	}

	/**
	 * 根据批次号，货品类型，货品型号查询二维码
	 * @param si
	 * @return
	 */
	@Transactional(readOnly = false)
	public Page<StorageInfo> findByPcTypeModel(Page<QrCode> page, StorageInfo si) {


		GoodsInfo goodsInfo = si.getGoodsInfo();
		QrCode temQr = new QrCode();
		String model = goodsInfo.getModel();
		if (StringUtils.isNotBlank(model)) {
			goodsInfo.setModelList(IKSegmenter.splitStr(model, false));
		}
		temQr.setGoodsInfo(goodsInfo);

		QrCode qr = si.getQrCode();
		if (null != qr && StringUtils.isNotBlank(qr.getState())) {
			temQr.setState(qr.getState());
		}
		dataRuleFilter(temQr);
		temQr.setPage(page);
		List<QrCode> qrCodeList = qrCodeMapper.findByPcTypeModel(temQr);

		List<StorageInfo> storageInfoList = new ArrayList<>();
		for (QrCode qrCode : qrCodeList) {
			GoodsInfo gi = qrCode.getGoodsInfo();
			StorageInfo storageInfo = new StorageInfo();
			storageInfo.setName(gi.getName());
			storageInfo.setType(gi.getType());
			storageInfo.setModel(gi.getModel());
			storageInfo.setGoodsInfo(gi);
			storageInfo.setAmount(gi.getAmount());
			storageInfo.setQrCode(qrCode);
			storageInfoList.add(storageInfo);
		}
		Page<StorageInfo> storageInfoPage = new Page<>();
		storageInfoPage.setList(storageInfoList);
		storageInfoPage.setCount(page.getCount());
		storageInfoPage.setPageNo(page.getPageNo());
		storageInfoPage.setPageSize(page.getPageSize());
		storageInfoPage.setOrderBy(page.getOrderBy());
		storageInfoPage.setFuncName(page.getFuncName());
		storageInfoPage.setFuncParam(page.getFuncParam());
		return storageInfoPage;
	}
}