package com.sunda.spmsoversea.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmsoversea.dto.WerksAllStorageInvSearchDTO;
import com.sunda.spmsoversea.dto.WerksStorageInvSearchDTO;
import com.sunda.spmsoversea.dto.WhsStorageInvSearchDTO;
import com.sunda.spmsoversea.dto.WhsStorageInventoryPrintDTO;
import com.sunda.spmsoversea.entity.WhsStorageInventory;
import com.sunda.spmsoversea.mapper.WhsStorageInventoryMapper;
import com.sunda.spmsoversea.service.IWhsStorageInventoryService;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.sunda.spmsoversea.constant.WhsStorageInventoryConstant.ADD;
import static com.sunda.spmsoversea.constant.WhsStorageInventoryConstant.SUB;

/**
 * <p>
 * 储位库存信息表 服务实现类
 * </p>
 *
 * @author Wayne
 * @since 2021-09-10
 */
@Slf4j
@Service("overseaWhsStorageInventoryServiceImpl")
public class WhsStorageInventoryServiceImpl extends ServiceImpl<WhsStorageInventoryMapper, WhsStorageInventory> implements IWhsStorageInventoryService {


    @Autowired
    WhsStorageInventoryMapper whsStorageInventoryMapper;

    /** 线程安全控制————海外仓储位库存操作，包括库存校验，operateType = add 加库存；operateType = sub 减库存；加减库存时 qty 都取正数；此法不带操作日志；*/
    @Override
    public synchronized ResponseResult updateWhsStorageInventory(String storageUuid, String materialNo, double qty, String operateType) {
        if (StringUtils.isEmpty(storageUuid) || StringUtils.isEmpty(materialNo)) {
            return ResponseResult.error().add("error", "storageUuid 或 materialNo 不能为空");
        }
        if (qty <= 0) {
            return ResponseResult.error().add("error", "qty 不能小于等于0");
        }
        try {
            QueryWrapper<WhsStorageInventory> queryWrapper = new QueryWrapper<WhsStorageInventory>().eq("UUID", storageUuid).eq("MATERIAL_NO", materialNo);
            WhsStorageInventory storageInventory = this.baseMapper.selectOne(queryWrapper);
            if (ADD.equals(operateType)) {
                // 加储位库存——已存在更新；不存在则新增；
                if (null != storageInventory) {
                    double quantity = storageInventory.getQuantity() + qty;
                    double availableQty = storageInventory.getAvailableQty() + qty;
                    WhsStorageInventory inventory = new WhsStorageInventory();
                    inventory.setQuantity(quantity);
                    inventory.setAvailableQty(availableQty);
                    this.baseMapper.update(inventory, queryWrapper);
                } else {
                    WhsStorageInventory whsStorageInventory = new WhsStorageInventory();
                    whsStorageInventory.setUuid(storageUuid);
                    whsStorageInventory.setMaterialNo(materialNo);
                    whsStorageInventory.setQuantity(qty);
                    whsStorageInventory.setAvailableQty(qty);
                    this.baseMapper.insert(whsStorageInventory);
                }
                return ResponseResult.success();
            }
            if (SUB.equals(operateType)) {
                // 减储位库存，操作数大于库存则返回错误提示；操作数等于库存则删除该库存；操作数小于库存则更新该库存；
                if (null != storageInventory) {
                    if (qty > storageInventory.getAvailableQty()) {
                        log.error(materialNo + "在储位" + storageUuid + "库存不足，请检查重试");
                        return ResponseResult.error(  materialNo + "在储位" + storageUuid + "库存不足，请检查重试");
                    }
//                  库存数量为0的不进行删除，海外仓库存明细需要查询库存记录 2022-07-15 xzp update  if (qty == storageInventory.getAvailableQty()) {
//                        this.baseMapper.delete(queryWrapper);
//                        return ResponseResult.success();
//                    }
                    if (qty <= storageInventory.getAvailableQty()) {
                        storageInventory.setQuantity(storageInventory.getQuantity() - qty);
                        storageInventory.setAvailableQty(storageInventory.getAvailableQty() - qty);
                        this.baseMapper.update(storageInventory, queryWrapper);
                        return ResponseResult.success();
                    }
                } else {
                    log.error(materialNo + "在储位" + storageUuid + "不存在，请检查重试");
                    return ResponseResult.error(  materialNo + "在储位" + storageUuid + "不存在，请检查重试");
                }
            }
            return ResponseResult.error().add("error", "操作类型不正确");
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: updateStorageInventoryM");
        }
    }

    @Override
    public WhsStorageInventory getWhsStorageInventory(String uuid, String materialNo) {
        if (StringUtils.isEmpty(uuid) || StringUtils.isEmpty(materialNo)){
            return null;
        }
        QueryWrapper<WhsStorageInventory> queryWrapper =
                new QueryWrapper<WhsStorageInventory>().eq("UUID", uuid).eq("MATERIAL_NO", materialNo);
        return this.baseMapper.selectOne(queryWrapper);
    }

    /** 本工厂 库存搜索：工厂、物料号、物料描述、库区、储位编号 —— 结果带具体储位信息，按储位给库存信息，工厂必输其余可选 */
    @Override
    public ResponseResult getWerksStorageInvList(WerksStorageInvSearchDTO werksStorageInvSearchDTO) {
        if (werksStorageInvSearchDTO == null || (StringUtils.isEmpty(werksStorageInvSearchDTO.getWerks()) && CollectionUtils.isEmpty(werksStorageInvSearchDTO.getWerksList()))){
            return ResponseResult.error("请求参数错误或查询工厂不能为空");
        }
        try {
            if(werksStorageInvSearchDTO.getSearchInfo()!=null && werksStorageInvSearchDTO.getSearchInfo().length()>0){
                String[] searchInfo = null;
                if(werksStorageInvSearchDTO.getSearchInfo().trim().indexOf("，")>=0){
                    searchInfo = werksStorageInvSearchDTO.getSearchInfo().trim().split("，");
                }else{
                    searchInfo = werksStorageInvSearchDTO.getSearchInfo().trim().split(",");
                }
                List<String> searchInfos = new ArrayList<String>();
                for (int i = 0; i < searchInfo.length; i++){
                    searchInfos.add(searchInfo[i].trim());
                }
                werksStorageInvSearchDTO.setSearchInfos(searchInfos);
            }else{
                werksStorageInvSearchDTO.setSearchInfos(null);
            }
            IPage iPage = werksStorageInvSearchDTO.getPage();
            List<Map<String, Object>> mapList =  new ArrayList<>();
            if("02".equals(werksStorageInvSearchDTO.getStorageType())){
                mapList = this.baseMapper.getWerksOldStorageInvList(iPage, werksStorageInvSearchDTO);
            }else{
                mapList = this.baseMapper.getWerksStorageInvList(iPage, werksStorageInvSearchDTO);
            }
            List<Map<String, Object>> marmList = new ArrayList<Map<String, Object>>();
            if(mapList!=null && mapList.size()>0){
                List<String> materialNo = new ArrayList<String>();
                for (int i = 0; i < mapList.size(); i++){
                    materialNo.add(mapList.get(i).get("materialNo").toString());
                }
                marmList = whsStorageInventoryMapper.getMaterialMarmByNo(materialNo);
            }
            return ResponseResult.success().add("whsStorageInvList", iPage.setRecords(mapList)).add("marmList", marmList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksStorageInvList");
        }
    }

    /** 获取条件下所有储位库存，不分页 */
    @Override
    public ResponseResult getWerksAllStorageInv(WerksAllStorageInvSearchDTO werksAllStorageInvSearchDTO) {
        if (werksAllStorageInvSearchDTO == null || StringUtils.isEmpty(werksAllStorageInvSearchDTO.getWerks())){
            return ResponseResult.error("请求参数错误或查询工厂不能为空");
        }
        try {
            List<Map<String, Object>> mapList = this.baseMapper.getWerksAllStorageInv(werksAllStorageInvSearchDTO);
            return ResponseResult.success().add("whsStorageInvList", mapList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksAllStorageInv");
        }
    }
    
    @Override
    public List<Map<String, Object>> getWerksAllStorageInvM(WerksAllStorageInvSearchDTO werksAllStorageInvSearchDTO) throws Exception {
    	if (werksAllStorageInvSearchDTO == null || StringUtils.isEmpty(werksAllStorageInvSearchDTO.getWerks())){
    		throw new Exception("请求参数错误或查询工厂不能为空");
    	}
    	try {
    		List<Map<String, Object>> mapList = this.baseMapper.getWerksAllStorageInvM(werksAllStorageInvSearchDTO);
    		return mapList;
    	}catch (Exception e){
    		e.printStackTrace();
    		throw new Exception("查询工厂下全部贸易货储位库存失败:"+e.getMessage());
    	}
    }

    /** 跨工厂 库存搜索：工厂、物料号、物料描述 —— 结果不带具体储位信息，按工厂物料求和，所有条件可选 */
    @Override
    public ResponseResult getStorageInvList(WhsStorageInvSearchDTO whsStorageInvSearchDTO) {
        if (whsStorageInvSearchDTO == null){
            return ResponseResult.error("请求参数错误");
        }
        try {
            if(whsStorageInvSearchDTO.getSearchInfo()!=null && whsStorageInvSearchDTO.getSearchInfo().length()>0){
                String[] searchInfo = null;
                if(whsStorageInvSearchDTO.getSearchInfo().trim().indexOf("，")>=0){
                    searchInfo = whsStorageInvSearchDTO.getSearchInfo().trim().split("，");
                }else{
                    searchInfo = whsStorageInvSearchDTO.getSearchInfo().trim().split(",");
                }
                List<String> searchInfos = new ArrayList<String>();
                for (int i = 0; i < searchInfo.length; i++){
                    searchInfos.add(searchInfo[i].trim());
                }
                whsStorageInvSearchDTO.setSearchInfos(searchInfos);
            }else{
                whsStorageInvSearchDTO.setSearchInfos(null);
            }
            IPage iPage = whsStorageInvSearchDTO.getPage();
            List<Map<String, Object>> mapList = this.baseMapper.getStorageInvList(iPage, whsStorageInvSearchDTO);
            return ResponseResult.success().add("whsStorageInventoryList", iPage.setRecords(mapList));
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksStorageInvList");
        }
    }

    /** 按工厂代码料号查询所有储位分布 */
    @Override
    public ResponseResult getWerksStorageByMaterialNo(String werks, String materialNo) {
        if (StringUtils.isEmpty(werks) || StringUtils.isEmpty(materialNo)){
            return ResponseResult.error("请求参数错误");
        }
        return ResponseResult.success().add("whsStorageInventory", this.baseMapper.getWhsStorageInventory(werks, materialNo));
    }
    
    /** 分页查询零库存明细 **/
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public ResponseResult getWerksStorageZeroInvList(WerksStorageInvSearchDTO werksStorageInvSearchDTO) {
		if (werksStorageInvSearchDTO == null || StringUtils.isEmpty(werksStorageInvSearchDTO.getWerks())){
            return ResponseResult.error("请求参数错误或查询工厂不能为空");
        }
        try {
            if(werksStorageInvSearchDTO.getSearchInfo()!=null && werksStorageInvSearchDTO.getSearchInfo().length()>0){
                String[] searchInfo = null;
                if(werksStorageInvSearchDTO.getSearchInfo().trim().indexOf("，")>=0){
                    searchInfo = werksStorageInvSearchDTO.getSearchInfo().trim().split("，");
                }else{
                    searchInfo = werksStorageInvSearchDTO.getSearchInfo().trim().split(",");
                }
                List<String> searchInfos = new ArrayList<String>();
                for (int i = 0; i < searchInfo.length; i++){
                    searchInfos.add(searchInfo[i].trim());
                }
                werksStorageInvSearchDTO.setSearchInfos(searchInfos);
            }else{
                werksStorageInvSearchDTO.setSearchInfos(null);
            }
            IPage iPage = werksStorageInvSearchDTO.getPage();
            List<Map<String, Object>> mapList = this.baseMapper.getWerksStorageZeroInvList(iPage, werksStorageInvSearchDTO);
            List<Map<String, Object>> marmList = new ArrayList<Map<String, Object>>();
            if(mapList!=null && mapList.size()>0){
                List<String> materialNo = new ArrayList<String>();
                for (int i = 0; i < mapList.size(); i++){
                    materialNo.add(mapList.get(i).get("materialNo").toString());
                }
                marmList = whsStorageInventoryMapper.getMaterialMarmByNo(materialNo);
            }
            return ResponseResult.success().add("whsStorageInvList", iPage.setRecords(mapList)).add("marmList", marmList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksStorageInvList");
        }
	}
	
	/** 获取条件下所有储位零库存，不分页 */
	@Override
	public ResponseResult getWerksAllZeroStorageInv(WerksAllStorageInvSearchDTO werksAllStorageInvSearchDTO) {
		if (werksAllStorageInvSearchDTO == null || StringUtils.isEmpty(werksAllStorageInvSearchDTO.getWerks())){
            return ResponseResult.error("请求参数错误或查询工厂不能为空");
        }
        try {
            List<Map<String, Object>> mapList = this.baseMapper.getWerksAllZeroStorageInv(werksAllStorageInvSearchDTO);
            return ResponseResult.success().add("whsStorageInvList", mapList);
        }catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error().add("error", e.getMessage() + "\nfunction name: getWerksAllStorageInv");
        }
	}
	
	public List<WhsStorageInventoryPrintDTO> materialPrint(String dsName,String datasetName,Map<String,Object> parameters) {
		String werks = (String) parameters.get("werks");
		String storageArea = (String) parameters.get("storageArea");
		String storageNo = (String) parameters.get("storageNo");
		String searchInfo = (String) parameters.get("searchInfo");
		String items = (String) parameters.get("itemList");
		String nowDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
		List<WhsStorageInventoryPrintDTO> returnList = new ArrayList<WhsStorageInventoryPrintDTO>();
		// 如果items不为空，说明是选择行来打印，否则根据条件查询数据打印
		if (StringUtils.isEmpty(items)) {
			WerksStorageInvSearchDTO dto = new WerksStorageInvSearchDTO();
			dto.setWerks(werks);
			dto.setStorageArea(storageArea);
			dto.setStorageNo(storageNo);
			if(StringUtils.isNotEmpty(searchInfo)){
                String[] searchInfoSplit = null;
                if(searchInfo.trim().indexOf("，")>=0){
                	searchInfoSplit = searchInfo.trim().split("，");
                }else{
                	searchInfoSplit = searchInfo.trim().split(",");
                }
                List<String> searchInfos = new ArrayList<String>();
                for (int i = 0; i < searchInfoSplit.length; i++){
                    searchInfos.add(searchInfoSplit[i].trim());
                }
                dto.setSearchInfos(searchInfos);
            }else{
                dto.setSearchInfos(null);
            }
            List<Map<String, Object>> mapList = this.baseMapper.getWerksStorageInvListByParam(dto);
			if (CollectionUtils.isNotEmpty(mapList)) {
				for (int i = 0; i < mapList.size(); i++) {
					WhsStorageInventoryPrintDTO print = new WhsStorageInventoryPrintDTO();
					print.setStorageNo(mapList.get(i).get("storageNo").toString());
					print.setMaterialNo(mapList.get(i).get("materialNo").toString());
					print.setPrintDate(nowDate);
					print.setMaterialZhName(mapList.get(i).get("materialZhDesc") != null ? mapList.get(i).get("materialZhDesc").toString() : "");
					print.setMaterialEnName(mapList.get(i).get("materialEnDesc") != null ? mapList.get(i).get("materialEnDesc").toString() : "");
					returnList.add(print);
				}
			}
		} else {
			String[] split = items.split(",");
			for (int i = 0; i < split.length; i++) {
				String[] split2 = split[i].split("_");
				WhsStorageInventoryPrintDTO dto = new WhsStorageInventoryPrintDTO();
				dto.setStorageNo(split2[0]);
				dto.setMaterialNo(split2[1]);
				dto.setPrintDate(nowDate);
				Map<String, Object> materialMap = this.baseMapper.selectMaterialSapByMaterialNumber(split2[1]);
				dto.setMaterialZhName(materialMap != null && materialMap.get("materialZhDesc") != null ? materialMap.get("materialZhDesc").toString() : "");
				dto.setMaterialEnName(materialMap != null && materialMap.get("materialEnDesc") != null ? materialMap.get("materialEnDesc").toString() : "");
				returnList.add(dto);
			}
		}
		return returnList;
	}
}
