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

import com.prolog.cs.biz.inbound.dao.rcv.RcvHeadersPicMapper;
import com.prolog.cs.biz.inbound.dto.PageParam;
import com.prolog.cs.biz.inbound.dto.rcv.RcvHeadersPicDTO;
import com.prolog.cs.biz.inbound.model.rcv.RcvHeadersPic;
import com.prolog.cs.biz.inbound.service.impl.BaseServiceImpl;
import com.prolog.cs.biz.inbound.service.rcv.RcvHeadersPicService;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.cs.biz.inbound.utils.UserUtils;
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 javax.validation.Validator;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class RcvHeadersPicServiceImpl extends BaseServiceImpl<RcvHeadersPic> implements RcvHeadersPicService {

	@Resource
	private RcvHeadersPicMapper mapper;

	@Resource
	private UserUtils userUtils;

	private final static String addMsg = "收货图片保存操作";
	private final static String editMsg = "收货图片编辑操作";
	private final static String batchAddMsg = "收货图片批量保存操作";
	private final static String batchEditMsg = "收货图片批量编辑操作";

	@Override
	public Object add(RcvHeadersPicDTO rcvHeadersPicDTO) {
		// TODO vaildate
		UserDTO userDTO = userUtils.getUserDTO();
		this.buildDefaultField(rcvHeadersPicDTO, false, userDTO,new Date());
		this.vaildateModel(rcvHeadersPicDTO, false, userDTO, 0, validator, addMsg);
		RcvHeadersPic rcvHeadersPic = new RcvHeadersPic();
		BeanUtils.copyProperties(rcvHeadersPicDTO, rcvHeadersPic);
		this.setBaseSysField(rcvHeadersPic, userDTO);
//		this.buildField(rcvHeadersPic, false, userDTO);
		this.mapper.save(rcvHeadersPic);
		return true;
	}

	@Override
	public Object edit(String pkId, RcvHeadersPicDTO rcvHeadersPicDTO) {
		UserDTO userDTO = userUtils.getUserDTO();
		this.vaildateModel(rcvHeadersPicDTO, true, userDTO, 0, validator, editMsg);
		RcvHeadersPic rcvHeadersPic = new RcvHeadersPic();
		BeanUtils.copyProperties(rcvHeadersPicDTO, rcvHeadersPic);
		this.setBaseSysField(rcvHeadersPic, true, userDTO);
//		this.buildField(rcvHeadersPic, true, userDTO);
		this.mapper.updateWithValidate(rcvHeadersPic,
				p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
		return true;
	}

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

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

	@Override
	public Page<RcvHeadersPicDTO> findList(RcvHeadersPicDTO rcvHeadersPicDTO, PageParam pageParam) {

		Criteria criteria = buildPageParam(pageParam, true, null, RcvHeadersPic.class);
		Restriction r = buildCondition(rcvHeadersPicDTO);
		criteria.setRestriction(r);
		this.startPage(pageParam);
		List<RcvHeadersPic> list = this.mapper.findByCriteria(criteria);
		Page<RcvHeadersPic> page = PageUtils.getPage(list);
		Page<RcvHeadersPicDTO> page2 = this.buildPage(page, (p) -> {
			RcvHeadersPicDTO target = new RcvHeadersPicDTO();
			BeanUtils.copyProperties(p, target);
			return target;
		});
		return page2;
	}

	@Override
	@Transactional
	public Object batchAdd(List<RcvHeadersPicDTO> rcvHeadersPicDTOList) {
		// TODO
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		int row = 0;
		for (RcvHeadersPicDTO rcvHeadersPicDTO : rcvHeadersPicDTOList) {
			row++;
			this.buildDefaultField(rcvHeadersPicDTO, false, userDTO,now);
			this.vaildateModel(rcvHeadersPicDTO, false, userDTO, row, validator, batchAddMsg);
//			this.vaildateModel(rcvHeadersPicDTO, false, userDTO, row);
			RcvHeadersPic rcvHeadersPic = new RcvHeadersPic();
			BeanUtils.copyProperties(rcvHeadersPicDTO, rcvHeadersPic);
			this.setBaseSysField(rcvHeadersPic, false, userDTO, now);
//			this.buildField(rcvHeadersPic, false, userDTO, now);
			this.mapper.save(rcvHeadersPic);
		}
		return true;
	}

	@Override
	@Transactional
	public Object batchEdit(List<RcvHeadersPicDTO> rcvHeadersPicDTOList) {
		// TODO
		UserDTO userDTO = userUtils.getUserDTO();
		Date now = new Date();
		int row = 0;
		for (RcvHeadersPicDTO rcvHeadersPicDTO : rcvHeadersPicDTOList) {
			row++;
			String rcvHeaderPicId = rcvHeadersPicDTO.getRcvHeaderPicId();
			if (canEdit(rcvHeaderPicId)) {
				this.vaildateModel(rcvHeadersPicDTO, true, userDTO, row, validator, batchEditMsg);
//				this.vaildateModel(rcvHeadersPicDTO, true, userDTO, row);
				RcvHeadersPic rcvHeadersPic = new RcvHeadersPic();
				BeanUtils.copyProperties(rcvHeadersPicDTO, rcvHeadersPic);
				this.setBaseSysField(rcvHeadersPic, true, userDTO, now);
//				this.buildField(rcvHeadersPic, true, userDTO, now);
				this.mapper.updateWithValidate(rcvHeadersPic,
						p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
			}

		}
		return true;
	}

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

	@Override
	public RcvHeadersPicDTO findByPkId(String pkId) {
		// TODO
		RcvHeadersPic rcvHeadersPic = this.findById(pkId);
		AssertUtils.notNull(rcvHeadersPic, "model empty!");
		RcvHeadersPicDTO rcvHeadersPicDTO = new RcvHeadersPicDTO();
		BeanUtils.copyProperties(rcvHeadersPic, rcvHeadersPicDTO);
		return rcvHeadersPicDTO;
	}

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

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

//	private void buildField(RcvHeadersPic rcvHeadersPic, Boolean editFlag, UserDTO userDTO) {
//		buildField(rcvHeadersPic, editFlag, userDTO, new Date());
//	}
//
//	private void buildField(RcvHeadersPic rcvHeadersPic, Boolean editFlag, UserDTO userDTO, Date now) {
//
//		Date gmtCreate = rcvHeadersPic.getGmtCreate();
//		Date gmtModified = rcvHeadersPic.getGmtModified();
//		String creator = rcvHeadersPic.getCreator();
//		String creatorName = rcvHeadersPic.getCreatorName();
//		String modifier = rcvHeadersPic.getModifier();
//		String modifierName = rcvHeadersPic.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))
//				rcvHeadersPic.setCreator(id);
//			if (ObjectUtils.isNull(creatorName))
//				rcvHeadersPic.setCreatorName(username);
//			if (ObjectUtils.isNull(gmtCreate))
//				rcvHeadersPic.setGmtCreate(now);
//			if (ObjectUtils.isNull(enterpriseId))
//				rcvHeadersPic.setEnterpriseId(enterpriseId);
//		}
//		if (ObjectUtils.isNull(modifier))
//			rcvHeadersPic.setModifier(id);
//		if (ObjectUtils.isNull(modifierName))
//			rcvHeadersPic.setModifierName(username);
//		if (ObjectUtils.isNull(gmtModified))
//			rcvHeadersPic.setGmtModified(now);
//		vaildateModelRepeated(rcvHeadersPic, editFlag, userDTO);
//	}

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

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

	private Restriction buildCondition(RcvHeadersPicDTO rcvHeadersPicDTO) {
		String picFilename = rcvHeadersPicDTO.getPicFilename();
		String rcvHeaderId = rcvHeadersPicDTO.getRcvHeaderId();
		Restriction eq1 = StringUtils.isBlank(picFilename) ? null : Restrictions.eq("picFilename", picFilename);
		Restriction eq2 = StringUtils.isBlank(rcvHeaderId) ? null : Restrictions.eq("rcvHeaderId", rcvHeaderId);
		return Restrictions.and(eq1, eq2);
	}

	@Override
	public Object batchAdd(List<RcvHeadersPicDTO> rcvHeadersPicDTOList, String masterId, UserDTO userDTO) {
		// 批量保存
		if (null == userDTO)
			userDTO = userUtils.getUserDTO();
		int i = 0;
		boolean editFlag = Boolean.FALSE;
		Date now = new Date();
		for (RcvHeadersPicDTO rcvHeadersPicDTO : rcvHeadersPicDTOList) {
			i++;
			// TODO 这里后期判断是否是更新或者更新
			// 头表id
			rcvHeadersPicDTO.setRcvHeaderId(masterId);
			this.buildDefaultField(rcvHeadersPicDTO, editFlag, userDTO,now);
			this.vaildateModel(rcvHeadersPicDTO, editFlag, userDTO, i, validator, "收货图片保存操作");
			RcvHeadersPic pic = new RcvHeadersPic();
			BeanUtils.copyProperties(rcvHeadersPicDTO, pic);
			this.setBaseSysField(pic, editFlag, userDTO, now);
			this.mapper.save(pic);
		}

		return true;
	}

//	private void vaildateModel(RcvHeadersPicDTO rcvHeadersPicDTO, boolean editFlag, UserDTO userDTO, int row) {
//		// 校验数据
//		Set<ConstraintViolation<RcvHeadersPicDTO>> validate = null;
//		if (!editFlag) {
//			// 添加校验
//			validate = validator.validate(rcvHeadersPicDTO, validAdd.class);
//		} else {
//			validate = validator.validate(rcvHeadersPicDTO, validEdit.class);
//		}
//		if (validate != null && !validate.isEmpty()) {
//			StringBuilder sb = new StringBuilder();
//			if (row > 0)
//				sb.append(String.format(VaildateConstant.ERROR_ROW_FORMAT, row));
//			validate.forEach((validation) -> {
//				String errorMsg = validation.getMessage();
//				String propertyName = validation.getPropertyPath().toString();
//				sb.append(String.format(VaildateConstant.ERROR_FIELD_FORMAT, propertyName))
//						.append(String.format(VaildateConstant.ERROR_MSG_FORMAT, errorMsg));
//			});
//			throw new ParameterException(sb.toString());
//		}
//	}

	private void buildDefaultField(RcvHeadersPicDTO rcvHeadersPicDTO, boolean editFlag, UserDTO userDTO, Date now) {
		// 构建基础字段
		if (!editFlag) {
			String executorUserid = rcvHeadersPicDTO.getExecutorUserid();
			String executorUserName = rcvHeadersPicDTO.getExecutorUserName();
			Date executorDate = rcvHeadersPicDTO.getExecutorDate();
			if (StringUtils.isBlank(executorUserid)) {
				rcvHeadersPicDTO.setExecutorUserid(userDTO.getId()); 
			}
			if (StringUtils.isBlank(executorUserName)) {
				rcvHeadersPicDTO.setExecutorUserName(userDTO.getUsername());
			}
			if (executorDate == null) {
				rcvHeadersPicDTO.setExecutorDate(now);
			}
		}
	}

	@Resource
	private Validator validator;
}
