package com.dk.mdm.service.ivt;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.model.pojo.PageList;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.mdm.controller.ivt.inventory.InventoryController;
import com.dk.mdm.infrastructure.convert.ivt.FreezeConvert;
import com.dk.mdm.infrastructure.convert.ivt.FreezeItemConvert;
import com.dk.mdm.mapper.ivt.FreezeItemMapper;
import com.dk.mdm.mapper.ivt.InventoryMapper;
import com.dk.mdm.model.pojo.ivt.Freeze;
import com.dk.mdm.mapper.ivt.FreezeMapper;
import com.dk.common.service.BaseService;
import com.dk.common.mapper.BaseMapper;
import com.dk.mdm.model.pojo.ivt.FreezeItem;
import com.dk.mdm.model.pojo.ivt.Inventory;
import com.dk.mdm.model.pojo.sale.Order;
import com.dk.mdm.model.pojo.sale.OrderItem;
import com.dk.mdm.model.query.ivt.FreezeItemQuery;
import com.dk.mdm.model.query.ivt.FreezeQuery;
import com.dk.mdm.model.query.sale.OrderItemQuery;
import com.dk.mdm.model.response.ivt.FreezeItemResponse;
import com.dk.mdm.model.response.ivt.FreezeResponse;
import com.dk.mdm.model.response.ivt.InventoryResponse;
import com.dk.mdm.model.response.sale.OrderItemResponse;
import com.dk.mdm.model.response.sale.OrderResponse;
import com.dk.mdm.model.vo.ivt.FreezeItemVO;
import com.dk.mdm.model.vo.ivt.FreezeVO;
import com.dk.mdm.model.vo.sale.OrderItemVO;
import com.dk.mdm.model.vo.sale.OrderVO;
import com.dk.mdm.service.common.CommonService;
import com.dk.mdm.service.ivt.inventory.InventoryService;
import com.dk.mdm.service.sale.OrderItemService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

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

@Service
@Transactional
public class FreezeService extends BaseService<Freeze> {

	@Override
	public BaseMapper<Freeze> getRepository() {
		return freezeMapper;
	}

	@Autowired
	private FreezeMapper freezeMapper;

	@Autowired
	private FreezeItemMapper freezeItemMapper;

	@Autowired
	private FreezeConvert freezeConvert;

	@Autowired
	private CommonService commonService;

	@Autowired
	private FreezeItemConvert freezeItemConvert;

	@Autowired
	private FreezeItemService freezeItemService;

	@Autowired
	private InventoryService inventoryService;

	@Autowired
	private InventoryMapper inventoryMapper;
	/**
	 * @desc   : 重写主键
	 * @author : 宋扬
	 * @date   : 2023/3/13 10:39
	 */
	@Override
	public String getPrimaryKey() {
		return "freeze_id";
	}

	/**
	 * @desc   : 条件查询
	 * @author : 宋扬
	 * @date   : 2023/2/29 10:40
	 */
	@Pagination
	public ResponseResultVO<PageList<FreezeResponse>> selectByCond(FreezeQuery freezeQuery) {
		return super.mergeListWithCount(freezeQuery, freezeMapper.selectByCond(freezeQuery),
				freezeMapper.countByCond(freezeQuery));
	}

	/**
	 * @desc   : 新建冻结单
	 * @author : 宋扬
	 * @date   : 2024/3/15 10:33
	 */
	@Transactional(rollbackFor = {Exception.class})
	public ResponseResultVO<?> insert(FreezeVO freezeVO) {
		// 转化实体
		Freeze freeze = freezeConvert.convertToPo(freezeVO);
		Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.Freeze.getName(), true);
		// 获取冻结状态 获取冻结日期（当前日期） 插入冻结表的实体
		freeze.setFreezeStatus(Constant.FreezeStatusType.ALLFREEZE.getName()).setFreezeDate(LocalDate.now())
				.setCusId(freezeVO.getCusId()).setMakeStaff(freezeVO.getMakeStaff()).setOrgId(freezeVO.getOrgId())
				.setAutoUnfreezeDate(freezeVO.getAutoUnfreezeDate()).setMakeTime(LocalDateTime.now())
				.setStaffId(freezeVO.getStaffId()).setFreezeId(codeMap.get("outId").toString()).setRemarks(freezeVO.getRemarks())
				.setFreezeNo(codeMap.get("outNote").toString()).setSumQuantity(freezeVO.getSumQuantity());
		// 先插入冻结单主表数据
		super.insert(freeze);
		// 插入冻结明细
		if (freezeVO.getItemList() != null && freezeVO.getItemList().size() > 0) {
			for (FreezeItemVO freezeItemVO : freezeVO.getItemList()) {
				FreezeItem freezeItem = freezeItemConvert.convertToPo(freezeItemVO);
				// 查询库存信息
				Inventory inventoryForUpdate=inventoryMapper.selectByIdForUpdate(freezeItemVO.getInvId());
				// 判断冻结量是否大于可售量
				if(inventoryForUpdate.getUsableQty().compareTo(inventoryForUpdate.getFreezeQty())== -1){
					throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.FREEZEQTY_NO_LESS_USABLEQTY.getMessage());
				}
				// 获取冻结主表uuid
				freezeItem.setFreezeId(freeze.getFreezeId());
				// 插入冻结单明细数据
				freezeItemMapper.insert(freezeItem);
				// 库存冻结量=库存冻结量+新建冻结量
				BigDecimal freezeqty=freezeItemVO.getFreezeQty().add(inventoryForUpdate.getFreezeQty());
				// 库存可售量=库存可售量+新建冻结量
				BigDecimal usableQt=inventoryForUpdate.getUsableQty().subtract(freezeItemVO.getFreezeQty());
				// 更新修改内容信息
				Inventory inventoryUpdate = new Inventory();
				// 赋值库存可售量、冻结量和库存ID值
				inventoryUpdate.setInvId(freezeItemVO.getInvId()).setFreezeQty(freezeqty).setUsableQty(usableQt);
				// 修改库存冻结量、可售量
				inventoryService.updateByUuid(inventoryUpdate);
			}
		}
		return ResponseResultUtil.success();
	}

	/**
	 * @desc   : 获取冻结单信息（解冻用）
	 * @author : 宋扬
	 * @date   : 2024/3/19 15:29
	 */
	public ResponseResultVO<?> getFreezeForUpdate(String id) {
		Map<String, Object> dataInfo = new HashMap<>();
		FreezeResponse freezeResponse = freezeMapper.selectById(id);
		dataInfo.put("data", freezeResponse);
		// 商品明细
		List<FreezeItemResponse> freezeItem = freezeItemMapper.selectByCond(new FreezeItemQuery().setFreezeId(id));
		dataInfo.put("dataItem", freezeItem);
		return ResponseResultUtil.success(dataInfo);
	}

	/**
	 * @desc   : 解冻
	 * @author : 宋扬
	 * @date   : 2024/3/20 8:57
	 */
	@Transactional(
			rollbackFor = {Exception.class}
	)
	public ResponseResultVO<?> update(FreezeVO freezeVO) {
		// 明细实体（避免并发，需要再查一遍）
		FreezeItem freezeItemForUpdate;
		// 转化实体
		Freeze freeze = freezeConvert.convertToPo(freezeVO);
		// 赋值全部解冻
		String freezeStatus=Constant.FreezeStatusType.ALLUNFREEZE.getName();
		// 解冻
		for (FreezeItemVO freezeItemVO : freezeVO.getItemList()) {
			// 查询锁表
			freezeItemForUpdate = freezeItemMapper.selectByIdForUpdate(freezeItemVO.getItemId());
			//
			FreezeItem freezeItem = freezeItemConvert.convertToPo(freezeItemVO);
			// 实际解冻量=现解冻量-原解冻量
			BigDecimal unfreezeQty=freezeItemVO.getUnfreezeQty().subtract(freezeItemForUpdate.getUnfreezeQty());
			// 修改冻结单明细解冻量
			freezeItemService.updateByUuid(freezeItem);
			// 根据冻结量和剩余冻结量不相等则冻结主表是部分解冻
			if(!freezeItem.getSurplusQty().equals(freezeItem.getFreezeQty()))
			{
				freezeStatus=Constant.FreezeStatusType.PARTUNFREEZE.getName();
			}
			// 查询库存信息
			Inventory inventoryForUpdate=inventoryMapper.selectByIdForUpdate(freezeItemVO.getInvId());
			// 库存冻结量=库存冻结量-实际解冻量
			BigDecimal freezeqty=inventoryForUpdate.getFreezeQty().subtract(unfreezeQty);
			// 库存可售量=库存可售量+实际解冻量
			BigDecimal usableQt=inventoryForUpdate.getUsableQty().add(unfreezeQty);
			// 更新修改内容信息
			Inventory inventoryUpdate = new Inventory();
			// 赋值库存可售量、冻结量和库存ID值
			inventoryUpdate.setInvId(freezeItemVO.getInvId()).setFreezeQty(freezeqty).setUsableQty(usableQt);
			// 修改库存冻结量、可售量
			inventoryService.updateByUuid(inventoryUpdate);
		}
		// 赋值冻结表状态和ID
		freeze.setFreezeId(freezeVO.getFreezeId()).setFreezeStatus(freezeStatus).setRemarks(freezeVO.getRemarks());
		// 更新主表冻结状态
		return ResponseResultUtil.success(super.updateByUuid(freeze));
	}


	/**
	 * @desc   : 全部解冻
	 * @author : 王英杰
	 * @date   : 2024/3/20 8:57
	 */
	@Transactional(
			rollbackFor = {Exception.class}
	)
	public ResponseResultVO<?> updateFreezeAll(String id) {

		// 赋值全部解冻
		String freezeStatus=Constant.FreezeStatusType.ALLUNFREEZE.getName();
		// 查询冻结单明细
		FreezeItemQuery freezeItemQuery = new FreezeItemQuery();
		freezeItemQuery.setFreezeId(id);
		List<FreezeItemResponse> itemList = freezeItemMapper.selectByCond(freezeItemQuery);
		// 解冻
		for (FreezeItemResponse freezeItemVO : itemList) {

			FreezeItem freezeItem = new FreezeItem();
			// 赋值实体
			freezeItem.setItemId(freezeItemVO.getItemId()).setUnfreezeQty(freezeItemVO.getSurplusQty())
					.setSurplusQty(BigDecimal.ZERO);
			// 修改冻结单明细解冻量
			freezeItemService.updateByUuid(freezeItem);
			// 查询库存信息
			Inventory inventoryForUpdate=inventoryMapper.selectByIdForUpdate(freezeItemVO.getInvId());
			// 库存冻结量=库存冻结量-实际解冻量
			BigDecimal freezeqty=inventoryForUpdate.getFreezeQty().subtract(freezeItemVO.getSurplusQty());
			// 库存可售量=库存可售量+实际解冻量
			BigDecimal usableQt=inventoryForUpdate.getUsableQty().add(freezeItemVO.getSurplusQty());
			// 更新修改内容信息
			Inventory inventoryUpdate = new Inventory();
			// 赋值库存可售量、冻结量和库存ID值
			inventoryUpdate.setInvId(freezeItemVO.getInvId()).setFreezeQty(freezeqty).setUsableQty(usableQt);
			// 修改库存冻结量、可售量
			inventoryService.updateByUuid(inventoryUpdate);
		}
		// 赋值冻结表状态和ID
		Freeze freeze=new Freeze();
		freeze.setFreezeId(id).setFreezeStatus(freezeStatus);
		// 更新主表冻结状态
		return ResponseResultUtil.success(super.updateByUuid(freeze));
	}


}
