package com.emergency.avenue.storage.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emergency.avenue.admin.api.entity.SysDept;
import com.emergency.avenue.admin.api.entity.SysDictItem;
import com.emergency.avenue.admin.api.entity.SysTreeDict;
import com.emergency.avenue.admin.mapper.SysTreeDictMapper;
import com.emergency.avenue.admin.service.SysDeptService;
import com.emergency.avenue.admin.service.SysDictItemService;
import com.emergency.avenue.common.excel.vo.ErrorMessage;
import com.emergency.avenue.storage.api.entity.InboundInfo;
import com.emergency.avenue.storage.api.entity.InboundMaterialInfo;
import com.emergency.avenue.storage.api.entity.OutboundMaterialInfo;
import com.emergency.avenue.storage.api.vo.InbountExcelVO;
import com.emergency.avenue.storage.mapper.InboundMapper;
import com.emergency.avenue.storage.mapper.InboundMaterialMapper;
import com.emergency.avenue.storage.service.InboundService;
import com.emergency.avenue.common.core.util.R;
import com.emergency.avenue.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class InboundServiceImpl extends ServiceImpl<InboundMapper, InboundInfo>  implements InboundService {
	private final InboundMapper inboundMapper;
	private final InboundMaterialMapper inboundMaterialMapper;
	private final SysTreeDictMapper sysTreeDictMapper;
	private final SysDeptService sysDeptService;
	private final SysDictItemService sysDictItemService;

	@Override
	@Transactional
	public R saveInbountAndMaterial(InboundInfo inboundInfo) {
		String deptId = SecurityUtils.getUser().getDeptId();
		String deptName = SecurityUtils.getUser().getAbbreviationName();
		List<InboundMaterialInfo> inboundMaterialInfos = inboundInfo.getInboundMaterialInfos();
		if (inboundMaterialInfos.size()>0) {
			inboundInfo.setSubmitTime(LocalDateTime.now());
			inboundInfo.setWarehouse(deptName);
			inboundInfo.setDeptId(deptId.toString());
			inboundInfo.setUserId(SecurityUtils.getUser().getId());
			BigDecimal bigDecimal=new BigDecimal("0");
			BigDecimal bigDecimalzj=new BigDecimal("0.000");
			for (InboundMaterialInfo inboundMaterialInfo:inboundMaterialInfos){
				bigDecimal=bigDecimal.add(new BigDecimal(inboundMaterialInfo.getQuantity()));
				bigDecimalzj=bigDecimalzj.add(new BigDecimal(inboundMaterialInfo.getTotalPrice()));
			}
			inboundInfo.setQuantity(bigDecimal.toString());
			inboundInfo.setTotalPrice(bigDecimalzj.toString());
			inboundMapper.insert(inboundInfo);
			for (InboundMaterialInfo inboundMaterialInfo:inboundMaterialInfos){
				inboundMaterialInfo.setInboundId(inboundInfo.getInboundId());
				inboundMaterialInfo.setMaterialId(null);
				inboundMaterialMapper.insert(inboundMaterialInfo);
			}
		}
		return R.ok("新增成功");
	}

	@Override
	@Transactional
	public R updateInbountAndMaterial(InboundInfo inboundInfo) {
		if (inboundInfo.getInboundId()!=null){
			List<InboundMaterialInfo> inboundMaterialInfos = inboundInfo.getInboundMaterialInfos();
			BigDecimal bigDecimal=new BigDecimal("0");
			BigDecimal bigDecimalzj=new BigDecimal("0.000");
			for (InboundMaterialInfo inboundMaterialInfo:inboundMaterialInfos){
				bigDecimal=bigDecimal.add(new BigDecimal(inboundMaterialInfo.getQuantity()));
				bigDecimalzj=bigDecimalzj.add(new BigDecimal(inboundMaterialInfo.getTotalPrice()));
			}
			inboundInfo.setQuantity(bigDecimal.toString());
			inboundInfo.setTotalPrice(bigDecimalzj.toString());
			inboundMapper.updateById(inboundInfo);
			LambdaQueryWrapper<InboundMaterialInfo> eq = new QueryWrapper<InboundMaterialInfo>().lambda().eq(InboundMaterialInfo::getInboundId, inboundInfo.getInboundId());
			inboundMaterialMapper.delete(eq);
			for (InboundMaterialInfo inboundMaterialInfo:inboundMaterialInfos){
				inboundMaterialInfo.setInboundId(inboundInfo.getInboundId());
				inboundMaterialInfo.setMaterialId(null);
				inboundMaterialMapper.insert(inboundMaterialInfo);
			}
		}
		return R.ok("修改成功");
	}

	@Override
	public R importIn(List<InbountExcelVO> excelVOList, BindingResult bindingResult) {
		List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
		if (CollUtil.isNotEmpty(errorMessageList)) {
			return R.failed(errorMessageList);
		}
		Map<String, SysTreeDict> sysTreeDicts = sysTreeDictMapper.getOrderDictList(1)
				.stream().collect(Collectors.toMap(SysTreeDict::getCode, d -> d, (p1, p2) -> p2));
		Map<String, String> deptMap = sysDeptService.list(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getDeptType, 3))
				.stream().collect(Collectors.toMap(SysDept::getAbbreviationName, SysDept::getDeptId));
		Map<String, Map<String, String>> sysDictItemList = sysDictItemService.selectDictItem()
				.stream().collect(Collectors.groupingBy(SysDictItem::getDictType,
						Collectors.toMap(SysDictItem::getLabel, SysDictItem::getItemValue, (p1, p2) -> p2)));
		Map<String, String> indoundType = sysDictItemList.get("indound_type");
		List<String>   notNeedExtraCalculateByMaterialName=Arrays.asList("编织袋","复膜编织布","长丝土工布","二布一膜土工布","3吋输水软管","2.5吋输水软管");
		List<String>   notNeedExtraCalculate=new ArrayList<>();
		List<SysTreeDict> treeDicts = sysTreeDictMapper.selectList(new QueryWrapper<SysTreeDict>().lambda().in(SysTreeDict::getName, notNeedExtraCalculateByMaterialName));
		if (!treeDicts.isEmpty()){
			notNeedExtraCalculate=treeDicts.stream().map(SysTreeDict::getId).collect(Collectors.toList());
		}
		for (InbountExcelVO excel : excelVOList) {
			SysTreeDict sysTreeDict = sysTreeDictMapper.selectOne(new QueryWrapper<SysTreeDict>().lambda().eq(SysTreeDict::getName, excel.getMaterialName()));
			String[] codePath = sysTreeDict.getPath().split("/");
			InboundInfo inboundInfo=new InboundInfo();
			InboundMaterialInfo inboundMaterialInfo=new InboundMaterialInfo();
			BeanUtil.copyProperties(excel, inboundInfo);
			BeanUtil.copyProperties(excel, inboundMaterialInfo);
			inboundInfo.setMaterialGroup(sysTreeDicts.get(codePath[1]).getId());
			inboundInfo.setMaterialType(sysTreeDicts.get(codePath[2]).getId());
			inboundInfo.setMaterialName(sysTreeDict.getId());
			String isAvailableZn = excel.getIsAvailable();
			if(isAvailableZn!=null&&!"".equals(isAvailableZn)){
				if ("是".equals(isAvailableZn)){
					inboundInfo.setIsAvailable("0");
					inboundMaterialInfo.setIsAvailable("0");
				}
				if ("否".equals(isAvailableZn)){
					inboundInfo.setIsAvailable("1");
					inboundMaterialInfo.setIsAvailable("1");
				}
			}
			String inboundTypeZn = excel.getInboundType();
			if (inboundTypeZn!=null&&!"".equals(inboundTypeZn)){
				String s = indoundType.get(inboundTypeZn);
				inboundInfo.setInboundType(s);
				inboundMaterialInfo.setInboundType(s);
			}
			inboundMaterialInfo.setMaterialGroup(sysTreeDicts.get(codePath[1]).getId());
			inboundMaterialInfo.setMaterialType(sysTreeDicts.get(codePath[2]).getId());
			inboundMaterialInfo.setMaterialName(sysTreeDict.getId());
			inboundMaterialInfo.setUnit(Optional.ofNullable(sysTreeDicts.get(codePath[3] + "01")).orElse(new SysTreeDict()).getId());
			inboundInfo.setSubmitTime(LocalDateTime.now());
			inboundInfo.setStatus("5");
			inboundInfo.setDeptId(deptMap.get(inboundInfo.getWarehouse()));
			if (notNeedExtraCalculate.contains(inboundInfo.getMaterialName())){
				inboundInfo.setTotalPrice(new BigDecimal(inboundInfo.getQuantity()).multiply(new BigDecimal(excel.getUnitPrice())).toString());
			}else{
				inboundInfo.setTotalPrice(new BigDecimal(inboundInfo.getQuantity()).multiply(new BigDecimal(excel.getUnitPrice())).divide(new BigDecimal("10000")).toString());
			}
			inboundMapper.insert(inboundInfo);
			inboundMaterialInfo.setTotalPrice(inboundInfo.getTotalPrice());
			inboundMaterialInfo.setInboundId(inboundInfo.getInboundId());
			inboundMaterialInfo.setMaterialTree(Arrays.asList(inboundMaterialInfo.getMaterialGroup(),
					inboundMaterialInfo.getMaterialType(),
					inboundMaterialInfo.getMaterialName(),inboundMaterialInfo.getUnit()));
			inboundMaterialMapper.insert(inboundMaterialInfo);
		}
		return R.ok();
	}
}
