package com.prolog.cs.biz.inbound.service.impl.task;

import com.prolog.cs.biz.inbound.dao.task.TaskRejectedDetailMapper;
import com.prolog.cs.biz.inbound.dto.PageParam;
import com.prolog.cs.biz.inbound.dto.rcv.RcvHDTO;
import com.prolog.cs.biz.inbound.dto.rcv.RcvLinesDTO;
import com.prolog.cs.biz.inbound.dto.rqc.RqcLinesDTO;
import com.prolog.cs.biz.inbound.dto.rqc.RqcReLinesDTO;
import com.prolog.cs.biz.inbound.dto.rqc.RqcRechekLinesDTO;
import com.prolog.cs.biz.inbound.dto.task.TaskRejectedDetailDTO;
import com.prolog.cs.biz.inbound.model.task.TaskRejectedDetail;
import com.prolog.cs.biz.inbound.service.impl.BaseServiceImpl;
import com.prolog.cs.biz.inbound.service.impl.processor.Helper.HostedHelper;
import com.prolog.cs.biz.inbound.service.task.TaskRejectedDetailService;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.cs.biz.inbound.utils.UserUtils;
import com.prolog.cs.biz.inbound.vo.RcvQueryVO;
import com.prolog.cs.biz.inbound.vo.task.TaskQueryVO;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.beans.BeanUtils;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.framework.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TaskRejectedDetailServiceImpl extends BaseServiceImpl<TaskRejectedDetail> implements TaskRejectedDetailService {

	@Resource
	private TaskRejectedDetailMapper mapper;

	@Resource
	private UserUtils userUtils;

	@Resource
	private HostedHelper hostedHelper;

	@Override
	public Object add(TaskRejectedDetailDTO taskRejectedDetailDTO) {
		// TODO vaildate
		UserDTO userDTO = userUtils.getUserDTO();
		TaskRejectedDetail taskRejectedDetail = new TaskRejectedDetail();
		BeanUtils.copyProperties(taskRejectedDetailDTO, taskRejectedDetail);
		this.vaildateModel(taskRejectedDetail, false, userDTO);
		this.buildField(taskRejectedDetail, false, userDTO);
//		this.mapper.save(taskRejectedDetail);
		return "";
	}

	@Override
	public Object edit(String pkId, TaskRejectedDetailDTO taskRejectedDetailDTO) {
		// TODO
		UserDTO userDTO = userUtils.getUserDTO();
		TaskRejectedDetail taskRejectedDetail = new TaskRejectedDetail();
		BeanUtils.copyProperties(taskRejectedDetailDTO, taskRejectedDetail);
		this.vaildateModel(taskRejectedDetail, true, userDTO);
		this.buildField(taskRejectedDetail, true, userDTO);
		this.mapper.updateWithValidate(taskRejectedDetail,
				p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
		return "";
	}

	@Override
	@Transactional
	public Object delIds(List<String> pkIdList) {
		// TODO
		pkIdList.stream().filter(p -> canEdit(p)).forEach(p -> this.mapper.deleteById(p, TaskRejectedDetail.class));
		return "";
	}

	@Override
	public Object deletePkId(String pkId) {
		// TODO
		if (canEdit(pkId))
			throw new BizException("can not del");
		this.mapper.deleteById(pkId, TaskRejectedDetail.class);
		return "";
	}

	@Override
	public Page<TaskRejectedDetailDTO> findList(TaskRejectedDetailDTO taskRejectedDetailDTO, PageParam pageParam) {
		Criteria criteria = Criteria.forClass(TaskRejectedDetail.class);
		Integer pageNum = null;
		Integer pageSize = null;
		Restriction r = null;
		if (pageParam == null) {
			pageNum = PageParam.DEFAULT_PAGE_NUM;
			pageSize = PageParam.DEFAULT_PAGE_SIZE;
		} else {
			pageNum = pageParam.getPageNum();
			pageSize = pageParam.getPageSize();
			TaskRejectedDetailDTO condition = taskRejectedDetailDTO;
			r = buildCondition(condition);
		}
		if (pageNum == null || pageNum == 0) {
			pageNum = PageParam.DEFAULT_PAGE_NUM;
		}
		if (pageSize == null || pageSize == 0) {
			pageSize = PageParam.DEFAULT_PAGE_SIZE;
		}
		criteria.setRestriction(r);
		Order order = Order.newInstance().desc("gmtModified");
		criteria.setOrder(order);
		PageUtils.startPage(pageNum, pageSize);
		List<TaskRejectedDetail> list = this.mapper.findByCriteria(criteria);
		List<TaskRejectedDetailDTO> collect = Optional.ofNullable(list).orElse(Collections.emptyList()).stream()
				.map(p -> {
					TaskRejectedDetailDTO target = new TaskRejectedDetailDTO();
					BeanUtils.copyProperties(p, target);
					return target;
				}).collect(Collectors.toList());
		Page<TaskRejectedDetail> page = PageUtils.getPage(list);
		Page<TaskRejectedDetailDTO> page2 = new Page<>();
		page2.setStartRow(page.getStartRow());
		page2.setEndRow(page.getEndRow());
		page2.setPageCount(page.getPageCount());
		page2.setPageNum(page.getPageNum());
		page2.setPageSize(page.getPageSize());
		page2.setTotalCount(page.getTotalCount());
		page2.setList(collect);
		return page2;
	}

	@Override
	@Transactional
	public Object batchAdd(List<TaskRejectedDetailDTO> taskRejectedDetailDTOList) {
		// TODO
		UserDTO userDTO = userUtils.getUserDTO();
		for (TaskRejectedDetailDTO taskRejectedDetailDTO : taskRejectedDetailDTOList) {
			TaskRejectedDetail taskRejectedDetail = new TaskRejectedDetail();
			BeanUtils.copyProperties(taskRejectedDetailDTO, taskRejectedDetail);
			this.vaildateModel(taskRejectedDetail, false, userDTO);
			this.buildField(taskRejectedDetail, false, userDTO);
//			this.mapper.save(taskRejectedDetail);
		}
		return "";
	}

	@Override
	@Transactional
	public Object batchEdit(List<TaskRejectedDetailDTO> taskRejectedDetailDTOList) {
		// TODO
		UserDTO userDTO = userUtils.getUserDTO();
		for (TaskRejectedDetailDTO taskRejectedDetailDTO : taskRejectedDetailDTOList) {
			TaskRejectedDetail taskRejectedDetail = new TaskRejectedDetail();
			BeanUtils.copyProperties(taskRejectedDetailDTO, taskRejectedDetail);
			this.vaildateModel(taskRejectedDetail, true, userDTO);
			this.buildField(taskRejectedDetail, true, userDTO);
			this.mapper.updateWithValidate(taskRejectedDetail,
					p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
		}
		return "";
	}

	@Override
	public List<TaskRejectedDetailDTO> findAll(TaskRejectedDetailDTO taskRejectedDetailDTO) {
		// TODO
		Criteria criteria = Criteria.forClass(TaskRejectedDetail.class);
		TaskRejectedDetailDTO condition = taskRejectedDetailDTO;
		Restriction r = buildCondition(condition);
		criteria.setRestriction(r);
		Order order = Order.newInstance().desc("gmtModified");
		criteria.setOrder(order);
		List<TaskRejectedDetail> list = this.mapper.findByCriteria(criteria);
		List<TaskRejectedDetailDTO> collect = Optional.ofNullable(list).orElse(Collections.emptyList()).stream()
				.map(p -> {
					TaskRejectedDetailDTO target = new TaskRejectedDetailDTO();
					BeanUtils.copyProperties(p, target);
					return target;
				}).collect(Collectors.toList());
		return collect;
	}

	@Override
	public TaskRejectedDetailDTO findByPkId(String pkId) {
		// TODO
		TaskRejectedDetail taskRejectedDetail = this.findById(pkId);
		AssertUtils.notNull(taskRejectedDetail, "model empty!");
		TaskRejectedDetailDTO taskRejectedDetailDTO = new TaskRejectedDetailDTO();
		BeanUtils.copyProperties(taskRejectedDetail, taskRejectedDetailDTO);
		return taskRejectedDetailDTO;
	}

	private TaskRejectedDetail findById(String id) {
		return this.mapper.findById(id, TaskRejectedDetail.class);
	}

	private void vaildateModel(TaskRejectedDetail taskRejectedDetail, Boolean editFlag, UserDTO userDTO) {
		if (!editFlag) {
			// TODO add
		} else {
			// TODO
		}
	}

	private void buildField(TaskRejectedDetail taskRejectedDetail, Boolean editFlag, UserDTO userDTO) {
		if (!editFlag) {
			// TODO add
		} else {
			// TODO edit
		}
		vaildateModelRepeated(taskRejectedDetail, editFlag, userDTO);
	}

	private void vaildateModelRepeated(TaskRejectedDetail taskRejectedDetail, Boolean editFlag, UserDTO userDTO) {
		if (!editFlag) {
			// TODO add
		} else {
			// TODO
		}
	}

	private boolean canEdit(String pkId) {
		boolean flag = true;
		TaskRejectedDetail taskRejectedDetail = this.findById(pkId);
		AssertUtils.notNull(taskRejectedDetail, "model empty!");
		// TODO
		if (true)
			flag = false;
		return flag;
	}

	private Restriction buildCondition(TaskRejectedDetailDTO taskRejectedDetailDTO) {
		// 构建查询条件
		String batchNum = taskRejectedDetailDTO.getBatchNum();
//		String cargoOwnerId = taskRejectedDetailDTO.getC
		String warehouseId = taskRejectedDetailDTO.getWarehouseId();
		String rcvHeaderId = taskRejectedDetailDTO.getRcvHeaderId();
		String rcvLineId = taskRejectedDetailDTO.getRcvLineId();
		String itemId = taskRejectedDetailDTO.getItemId();

		Restriction r0 = Restrictions.eq("enterpriseId", userUtils.getEnterpriseId());
//		Restriction r1 = StringUtils.isBlank(cargoOwnerId) ? null : Restrictions.eq("cargoOwnerId", cargoOwnerId);
		Restriction r2 = StringUtils.isBlank(warehouseId) ? null : Restrictions.eq("warehouseId", warehouseId);
		Restriction r3 = StringUtils.isBlank(rcvHeaderId) ? null : Restrictions.eq("rcvHeaderId", rcvHeaderId);
		Restriction r4 = StringUtils.isBlank(rcvLineId) ? null : Restrictions.eq("rcvLineId", rcvLineId);
		Restriction r5 = StringUtils.isBlank(itemId) ? null : Restrictions.eq("itemId", itemId);
		Restriction r6 = StringUtils.isBlank(batchNum) ? null : Restrictions.like("batchNum", "%" + batchNum + "%");

		return Restrictions.and(r0, r2, r3, r4, r5, r6);
	}

	@Override
	public Object excuteTask(List<RcvLinesDTO> rcvLinesDTO, String mtlOwnerId, String warehouseId,boolean isAuto) {
		// TODO 创建收货拒绝任务
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		int row =1000;
		for (RcvLinesDTO rcvLinesDTO2 : rcvLinesDTO) {
			TaskRejectedDetail detail = new TaskRejectedDetail();
			BeanUtils.copyProperties(rcvLinesDTO2, detail);
			// 是否构建缺失字段
			row ++;
			this.buildField(detail, false, userDTO, now);
			detail.setWarehouseId(warehouseId);
			detail.setAsnHeaderId(rcvLinesDTO2.getAsnHeaderId());
			detail.setAsnLineId(rcvLinesDTO2.getAsnLineId());
			detail.setSrcHeaderId(rcvLinesDTO2.getSrcHeaderId());
			detail.setSrcLineId(rcvLinesDTO2.getSrcLineId());
			detail.setRefType(0);
			this.mapper.save(detail);
		}
		return true;
	}


	private void buildDefaultField(TaskRejectedDetail detail, boolean editFlag, UserDTO userDTO, Date now) {
		detail.setActiveFlag("1"); // 默认作业标识可用
		detail.setStatus("1"); // 默认待质检(?字义不明确)
//		if (!editFlag && ObjectUtils.isNull(activeFlag)) {
//			
//		}
		String status = detail.getStatus();
		if (!editFlag && ObjectUtils.isNull(status)) {
			detail.setStatus("1"); // 默认待质检(?字义不明确)
		}
		detail.setDataVersion(0);
//		Integer isSpilt = detail.getIsSpilt();
//		if (!editFlag && ObjectUtils.isNull(isSpilt)) {
//			detail.setIsSpilt(0);
//		}
//		if (!editFlag) {
//			detail.setDataVersion(0);
//		}
	}
	
	private void buildField(TaskRejectedDetail detail, boolean editFlag, UserDTO userDTO, Date now) {
		// 构建系统基础字段
		Date gmtCreate = detail.getGmtCreate();
		Date gmtModified = detail.getGmtModified();
		String creator = detail.getCreator();
		String creatorName = detail.getCreatorName();
		String modifier = detail.getModifier();
		String modifierName = detail.getModifierName();
		String id = userDTO.getId();
		String enterpriseId = userDTO.getEnterpriseId();
		String username = userDTO.getUsername();
		if (null == now)
			now = new Date();
		if (!editFlag) {
			if (ObjectUtils.isNull(creator))
				detail.setCreator(id);
			if (ObjectUtils.isNull(creatorName))
				detail.setCreatorName(username);
			if (ObjectUtils.isNull(gmtCreate))
				detail.setGmtCreate(now);
			detail.setEnterpriseId(enterpriseId);

		}
		if (ObjectUtils.isNull(modifier))
			detail.setModifier(id);
		if (ObjectUtils.isNull(modifierName))
			detail.setModifierName(username);
		if (ObjectUtils.isNull(gmtModified))
			detail.setGmtModified(now);
		vaildateModelRepeated(detail, editFlag, userDTO);
		this.buildDefaultField(detail, false, userDTO, now);
	}

	@Override
	public Object excuteTask2(List<RqcLinesDTO> rqcLinesList,boolean isAuto) {
		// TODO 创建质检拒绝任务
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		for (RqcLinesDTO rqcLinesDTO : rqcLinesList) {
			TaskRejectedDetail detail = new TaskRejectedDetail();
			BeanUtils.copyProperties(rqcLinesDTO, detail);
			// 是否构建缺失字段
			this.buildField(detail, false, userDTO, now);
			detail.setRefType(1);
			detail.setRefBillId(rqcLinesDTO.getRqcHeaderId());
			detail.setRefBillNo(rqcLinesDTO.getRqcHeaderNo());
			detail.setRefLineId(rqcLinesDTO.getRqcLineId());
//			this.mapper.save(detail);
		}
		return true;
	}

	@Override
	public Object excuteTask3(List<RqcLinesDTO> rqcLinesList,boolean isAuto) {
		// TODO 创建验收拒绝任务
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		for (RqcLinesDTO rqcLinesDTO : rqcLinesList) {
			TaskRejectedDetail detail = new TaskRejectedDetail();
			BeanUtils.copyProperties(rqcLinesDTO, detail);
			// 是否构建缺失字段
			this.buildField(detail, false, userDTO, now);
			detail.setRefType(1);
			detail.setRefBillId(rqcLinesDTO.getRqcHeaderId());
			detail.setRefBillNo(rqcLinesDTO.getRqcHeaderNo());
			detail.setRefLineId(rqcLinesDTO.getRqcLineId());
			this.mapper.save(detail);
		}
		return true;
	}

	@Override
	public Object excuteTask33(List<RqcRechekLinesDTO> rqcRechekLinesList) {
		// TODO 创建复检拒收任务
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		for (RqcRechekLinesDTO rqcRechekLinesDTO : rqcRechekLinesList) {
			TaskRejectedDetail detail = new TaskRejectedDetail();
			BeanUtils.copyProperties(rqcRechekLinesDTO, detail);
			// 是否构建缺失字段
			this.buildField(detail, false, userDTO, now);
//			this.mapper.save(detail);
		}
		return true;
	}

	@Override
	public Object excuteTask3(List<RqcReLinesDTO> rqcReLinesList,boolean isAuto, String regValue, String warehouserId) {
		// TODO 创建复检拒收任务
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		// 需要代管出库的明细
		List<RqcReLinesDTO> outHosted = new ArrayList<>();
		for (RqcReLinesDTO rqcReLinesDTO : rqcReLinesList) {
			// 如果 操作来源单类型为 3-收货待处理 或 4-质检待处理 且 业务参数是否进入代管子流程为1，则需要代管出库
			if (("1".equals(rqcReLinesDTO.getHostedStatus()) || "2".equals(rqcReLinesDTO.getHostedStatus()))
			&& ObjectUtils.isNotNull(regValue) && "1".equals(regValue)) {
				outHosted.add(rqcReLinesDTO);
			}

			TaskRejectedDetail detail = new TaskRejectedDetail();
			BeanUtils.copyProperties(rqcReLinesDTO, detail);
			// 是否构建缺失字段
			this.buildField(detail, false, userDTO, now);
//			this.mapper.save(detail);
		}

		if (ObjectUtils.isNotNull(outHosted)) {
			// 代管出库操作
			String inType = "7";    // 入库类型-代管出库
			String status = "1";    // 库存状态-正常
			hostedHelper.rqcReLinesOutHosted(outHosted, inType, status, userDTO, now, warehouserId);
		}

		return true;
	}

	@Override
	public Page<RcvHDTO> extractRcvHWithNativeSql(RcvQueryVO rcvQueryVO, PageParam pageParam) {
		String enterpriseId = userUtils.getEnterpriseId();
		rcvQueryVO.setEnterpriseId(enterpriseId);
		this.startPage(pageParam);
		List<RcvHDTO> list = this.mapper.extractRcvHWithNativeSql(rcvQueryVO);
		return PageUtils.getPage(list);
	}

	@Override
	public Page<TaskRejectedDetailDTO> extractTaskWithNativeSql(TaskQueryVO queryVO, PageParam pageParam) {
		String enterpriseId = userUtils.getEnterpriseId();
		queryVO.setEnterpriseId(enterpriseId);
		this.startPage(pageParam);
		List<TaskRejectedDetailDTO> list = this.mapper.findList(queryVO);
		return PageUtils.getPage(list);
	}

}
