/**
 * BladeX Commercial License Agreement
 * Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
 * <p>
 * Use of this software is governed by the Commercial License Agreement
 * obtained after purchasing a license from BladeX.
 * <p>
 * 1. This software is for development use only under a valid license
 * from BladeX.
 * <p>
 * 2. Redistribution of this software's source code to any third party
 * without a commercial license is strictly prohibited.
 * <p>
 * 3. Licensees may copyright their own code but cannot use segments
 * from this software for such purposes. Copyright of this software
 * remains with BladeX.
 * <p>
 * Using this software signifies agreement to this License, and the software
 * must not be used for illegal purposes.
 * <p>
 * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
 * not liable for any claims arising from secondary or illegal development.
 * <p>
 * Author: Chill Zhuang (bladejava@qq.com)
 */
package org.springblade.modules.material.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.common.cache.DictCache;
import org.springblade.common.enums.DictEnum;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.fitting.constant.FittingConstant;
import org.springblade.modules.fitting.pojo.entity.PlatformFittingApplyEntity;
import org.springblade.modules.fitting.pojo.vo.AddBhVo;
import org.springblade.modules.fitting.pojo.vo.OperaAddFittingBatchVo;
import org.springblade.modules.flowable.processForm.utils.GuardUtils;
import org.springblade.modules.material.pojo.dto.MaterialDTO;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.modules.material.mapper.MaterialMapper;
import org.springblade.modules.material.pojo.entity.MaterialEngineerEntity;
import org.springblade.modules.material.pojo.entity.MaterialEntity;
import org.springblade.modules.material.pojo.entity.MaterialOperationEntity;
import org.springblade.modules.material.pojo.vo.EmpFittingDetailVo;
import org.springblade.modules.material.pojo.vo.EmpGetFittingOutVo;
import org.springblade.modules.material.pojo.vo.MaterialVO;
import org.springblade.modules.material.service.IMaterialOutboundService;
import org.springblade.modules.material.service.IMaterialService;
import org.springblade.modules.nh.excel.InefficientSettingExcel;
import org.springblade.modules.nh.excel.MaterialExcel;
import org.springblade.modules.nh.pojo.entity.InefficientSettingEntity;
import org.springblade.modules.operation.mapper.OperationSiteEmployeeMapper;
import org.springblade.modules.operation.pojo.entity.OperationSiteEmployeeEntity;
import org.springblade.modules.operation.pojo.entity.OperationSiteEntity;
import org.springblade.modules.operation.service.impl.OperationSiteServiceImpl;
import org.springblade.modules.order.pojo.vo.SelectVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 物料库存 服务实现类
 *
 * @author cswang
 * @since 2024-08-25
 */
@Service
public class MaterialServiceImpl extends BaseServiceImpl<MaterialMapper, MaterialEntity> implements IMaterialService {
	@Autowired
	IMaterialOutboundService outboundService;

	@Autowired
	MaterialOperationServiceImpl operationService;

	@Autowired
	MaterialEngineerServiceImpl engineerService;

	@Autowired
	OperationSiteServiceImpl siteService;

	@Autowired
	OperationSiteEmployeeMapper employeeMapper;

	@Override
	public IPage<MaterialVO> selectMaterialPage(IPage<MaterialVO> page, MaterialVO material) {
		return page.setRecords(baseMapper.selectMaterialPage(page, material));
	}


	@Override
	public List<MaterialExcel> exportMaterial(Wrapper<MaterialEntity> queryWrapper) {
		List<MaterialExcel> ret = new ArrayList<>();
		List<MaterialEntity> materialList = baseMapper.exportMaterial(queryWrapper);
		materialList.forEach(material -> {
			MaterialExcel excel = new MaterialExcel();
			BeanUtil.copyProperties(material, excel);
			excel.setBrandStr(DictCache.getValue(DictEnum.BRAND, material.getBrand()));
			excel.setTypeStr(DictCache.getValue(DictEnum.WL_TYPE, material.getType()));
			ret.add(excel);
		});
		return ret;
	}

	@Override
	public void importMaterial(List<MaterialExcel> data, Boolean isCovered) {
		List<MaterialEntity> materialEntities = new ArrayList<>();
		BladeUser user = AuthUtil.getUser();
		boolean isRepeat = false;
		for(MaterialExcel item: data) {
			GuardUtils.notBlank(item.getName(), "物料名称不能为空");
			GuardUtils.notBlank(item.getTypeStr(), "物料类型不能为空");
			GuardUtils.notBlank(item.getModel(), "物料型号不能为空");
			GuardUtils.notBlank(item.getPower(), "物料规格不能为空");
			GuardUtils.notBlank(item.getBrandStr(), "物料品牌不能为空");
			LambdaQueryWrapper<MaterialEntity> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(MaterialEntity::getCode,item.getCode());
			if(count(queryWrapper)>0){
				throw new ServiceException("物料编码重复");
			}
			String type = DictCache.getKey(DictEnum.WL_TYPE, item.getTypeStr());
			String brand = DictCache.getKey(DictEnum.BRAND, item.getBrandStr());
			if(StringUtil.isBlank(type)){
				throw new ServiceException("物料类型系统中不存在");
			}
			if(StringUtil.isBlank(brand)){
				throw new ServiceException("物料品牌系统中不存在");
			}
			MaterialEntity entity = new MaterialEntity();
			BeanUtil.copyProperties(item, entity);

			if(entity.getRetailPrice()== null){
				entity.setRetailPrice(0.0);
			}
			if(entity.getStock()== null){
				entity.setStock(0);
			}

			entity.setType(type);
			entity.setBrand(brand);
			materialEntities.add(entity);
		}
		if(CollectionUtil.isNotEmpty(materialEntities)){
			this.saveBatch(materialEntities);
		}

		for(MaterialEntity entity:materialEntities){
			if(entity.getStock()>0){
				outboundService.saveMateInkeep(entity,"1",user, FittingConstant.KEEP_FORM_IN);
			}
		}


	}

	@Override
	public MaterialDTO getMaterialDetailByCode(String materialCode) {
		return baseMapper.getMaterialDetailByCode(materialCode);
	}

	@Override
	public MaterialEntity getByMaterialCode(String materialCode) {
		LambdaQueryWrapper<MaterialEntity> queryWrapper=new LambdaQueryWrapper<>();
		queryWrapper.eq(MaterialEntity::getCode,materialCode);
		queryWrapper.eq(MaterialEntity::getIsDeleted, BladeConstant.DB_NOT_DELETED);
		MaterialEntity materialEntity=getOne(queryWrapper);
		return materialEntity;
	}


	public MaterialDTO getMaterialById(String materialId){
		MaterialDTO materialEntityDto= baseMapper.getMaterialById(materialId);
		return materialEntityDto;
	}

	//工程师领取出库
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean empGetFittingOut(EmpGetFittingOutVo empGetFittingOutVo) {
		List<EmpFittingDetailVo> detailVoList=empGetFittingOutVo.getDetailVoList();
		BladeUser user = AuthUtil.getUser();
		OperationSiteEntity site=null;
		if("3".equals(user.getDeptId())){
			site = siteService.findSiteByUserId(user.getUserId());
		}else {
			OperationSiteEmployeeEntity emp = employeeMapper.findByuserId(user.getUserId());
			site = siteService.getById(emp.getSiteId());
		}
		if("2".equals(site.getPayTheDeposit())){  //未缴纳保证金
			throw new ServiceException("运营商未缴纳保证金，不能工程师领取物料！");
		}
		OperationSiteEmployeeEntity emp = employeeMapper.findByuserId(Long.valueOf(empGetFittingOutVo.getEmpUserId()));
		if(emp==null || !emp.getSiteId().equals(site.getId())){
			throw new ServiceException("未找到服务工程师信息！");
		}
		log.debug(".....empGetFittingOut size:"+detailVoList.size());
		Map<Long,MaterialOperationEntity> stockMap=new HashMap<>();
		Map<Long,MaterialEngineerEntity> empStockMap=new HashMap<>();
		for(EmpFittingDetailVo detailVo:detailVoList){
			log.debug(".....empGetFittingOut detailVo.getmaterialId:"+detailVo.getMaterialId());
			//获取物料信息
			MaterialDTO materialEntity=getMaterialById(detailVo.getMaterialId());

			//获取运营商物料库存
			MaterialOperationEntity siteMater=stockMap.get(materialEntity.getId());
			if(siteMater==null){
				siteMater = operationService.findByMateId(detailVo.getMaterialId(),site.getId());
			}
			if(siteMater==null){
				throw  new ServiceException(materialEntity.getName()+"，运营商物料库存不足");
			}
			siteMater.setStock(siteMater.getStock()-detailVo.getApplyNum());
			if(siteMater.getStock()<0){
				throw  new ServiceException(materialEntity.getName()+"，物料库存不足");
			}
			stockMap.put(materialEntity.getId(),siteMater);
			//工程师添加库存
			MaterialEngineerEntity empStock=empStockMap.get(materialEntity.getId());
			if(empStock==null){
				empStock = engineerService.getEngineerStock(empGetFittingOutVo.getEmpUserId(),materialEntity.getId().toString());
			}
			if(empStock ==null){
				empStock = new MaterialEngineerEntity();
				empStock.setMaterialId(materialEntity.getId());
				empStock.setOperationId(site.getId());
				empStock.setOperationName(site.getName());
				empStock.setEngineerId(Long.valueOf(empGetFittingOutVo.getEmpUserId()));
				empStock.setEngineerName(emp.getName());
				empStock.setCode(materialEntity.getCode());
				empStock.setName(materialEntity.getName());
				empStock.setType(materialEntity.getType());
				empStock.setModel(materialEntity.getModel());
				empStock.setPower(materialEntity.getPower());
				empStock.setDescription(materialEntity.getDescription());
				empStock.setBrand(materialEntity.getBrand());
				empStock.setStock(detailVo.getApplyNum());
				empStock.setCreateUser(user.getUserId());
				empStock.setCreateTime(new Date());
				empStock.setIsDeleted(0);
			}else{
				empStock.setStock(empStock.getStock()+detailVo.getApplyNum());
			}
			empStockMap.put(materialEntity.getId(),empStock);
			//生成运维商出库记录
			outboundService.savekeep(materialEntity,FittingConstant.KEEP_FORM_OUT,user,"2","2",site.getId()
				,"",site.getName(),detailVo.getApplyNum(),"",detailVo.getApplyMarks());
			//生成工程师入库记录
			outboundService.savekeep(materialEntity,FittingConstant.KEEP_FORM_IN,user,"6","1",site.getId()
				,empGetFittingOutVo.getEmpUserId(),emp.getName(),detailVo.getApplyNum(),detailVo.getRelateOrderId(),detailVo.getApplyMarks());

		}

		//保存工程师库存变动信息
		for(Map.Entry<Long, MaterialEngineerEntity> e : empStockMap.entrySet()){
			MaterialEngineerEntity engineerEntity=e.getValue();
			if(!engineerService.updateById(engineerEntity)){
				throw new ServiceException("保存工程师库存变动信息失败！");
			}
		}
		//保存运营商库存变动信息
		for(Map.Entry<Long, MaterialOperationEntity> e : stockMap.entrySet()){
			MaterialOperationEntity opeartionEntity=e.getValue();
			if(!operationService.saveOrUpdate(opeartionEntity)){
				throw new ServiceException("保存运营商库存变动信息失败！");
			}
		}
		return true;
	}

	@Override
	public List<SelectVo> getOrderListByNumber(String number) {
		BladeUser user = AuthUtil.getUser();
		String siteId="";
		if("3".equals(user.getDeptId())){
			OperationSiteEntity site = siteService.findSiteByUserId(user.getUserId());
			siteId=site.getId();
		}else {
			OperationSiteEmployeeEntity emp = employeeMapper.findByuserId(user.getUserId());
			OperationSiteEntity site = siteService.getById(emp.getSiteId());
			siteId=site.getId();
		}
		List<SelectVo> list=baseMapper.getOrderListByNumber(number,siteId);
		return list;
	}
}
