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

import com.prolog.cs.biz.inbound.constant.BizConstant;
import com.prolog.cs.biz.inbound.dao.rcv.RcvHeadersProfilesMapper;
import com.prolog.cs.biz.inbound.dto.PageParam;
import com.prolog.cs.biz.inbound.dto.rcv.RcvHeadersProfilesDTO;
import com.prolog.cs.biz.inbound.model.rcv.RcvHeadersProfiles;
import com.prolog.cs.biz.inbound.service.impl.BaseServiceImpl;
import com.prolog.cs.biz.inbound.service.rcv.RcvHeadersProfilesService;
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.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 RcvHeadersProfilesServiceImpl extends BaseServiceImpl<RcvHeadersProfiles>
		implements RcvHeadersProfilesService {

	@Resource
	private RcvHeadersProfilesMapper mapper;

	@Resource
	private UserUtils userUtils;

	@Resource
	private Validator validator;

	private final String serviceAddMsg = "收货拓展新增操作";

	private final String serviceEditMsg = "收货拓展新增操作";

	@Override
	public Object add(RcvHeadersProfilesDTO rcvHeadersProfilesDTO) {
		UserDTO userDTO = userUtils.getUserDTO();
		this.buildDefaultField(rcvHeadersProfilesDTO,userDTO);
		
		// 校验字段
		super.vaildateModel(rcvHeadersProfilesDTO, false, userDTO, 0, validator, serviceAddMsg);
		// copy数据
		RcvHeadersProfiles rcvHeadersProfiles = new RcvHeadersProfiles();
		BeanUtils.copyProperties(rcvHeadersProfilesDTO, rcvHeadersProfiles);
		this.setBaseSysField(rcvHeadersProfiles, userDTO);
		String warehouseCode = rcvHeadersProfilesDTO.getWarehouseCode();
		String customerCode = rcvHeadersProfilesDTO.getCustomerCode();
		String vendorCode = rcvHeadersProfilesDTO.getVendorCode();
		rcvHeadersProfiles.setVendorNum(vendorCode);
		rcvHeadersProfiles.setCustomerNum(customerCode);
		rcvHeadersProfiles.setWarehouseNum(warehouseCode);
		// 校验数据库重复
		this.vaildateModelRepeated(rcvHeadersProfiles, false, userDTO);
		// 保存
		this.mapper.save(rcvHeadersProfiles);
		return rcvHeadersProfiles.getRcvHeaderId();
	}

	/**
	 * 构建默认字段
	 * @param rcvHeadersProfilesDTO
	 * @param userDTO
	 */
	private void buildDefaultField(RcvHeadersProfilesDTO rcvHeadersProfilesDTO, UserDTO userDTO) {
		String rcvType = rcvHeadersProfilesDTO.getRcvType();
		if (rcvType.equals(BizConstant.HOSTED_IN) || rcvType.equals(BizConstant.WAIT_CHECK_IN)) {
			// 代管,待检默认给次要信息
			String transportationParty = rcvHeadersProfilesDTO.getTransportationParty();
			if (StringUtils.isBlank(transportationParty)) {
				transportationParty = "运输方无";
			}
			String carriername = rcvHeadersProfilesDTO.getCarriername();
			if (StringUtils.isBlank(carriername)) {
				carriername = "运输单位无";
			}
			Date shipFromDate = rcvHeadersProfilesDTO.getShipFromDate();
			if (ObjectUtils.isNull(shipFromDate)) {
				shipFromDate = new Date();
			}
			String shipFromAdd = rcvHeadersProfilesDTO.getShipFromAdd();
			if (StringUtils.isBlank(shipFromAdd)) {
				shipFromAdd = "发运地点无";
			}
			Integer onPassageDays = rcvHeadersProfilesDTO.getOnPassageDays();
			if (ObjectUtils.isNull(onPassageDays)) {
				onPassageDays = 90;
			}
			String shipType = rcvHeadersProfilesDTO.getShipType();
			if (StringUtils.isBlank(shipType)) {
				shipType = "运输方式无";
			}
			rcvHeadersProfilesDTO.setTransportationParty(transportationParty);
			rcvHeadersProfilesDTO.setCarriername(carriername);
			rcvHeadersProfilesDTO.setShipFromAdd(shipFromAdd);
			rcvHeadersProfilesDTO.setShipFromDate(shipFromDate);
			rcvHeadersProfilesDTO.setOnPassageDays(onPassageDays);
			rcvHeadersProfilesDTO.setShipType(shipType);
			
		}
		
	}

	@Override
	public RcvHeadersProfilesDTO findByPkId(String pkId) {
		// 主键id查询
		RcvHeadersProfiles rcvHeadersProfiles = this.findById(pkId);
		AssertUtils.notNull(rcvHeadersProfiles, "收货拓展数据为空!");
		RcvHeadersProfilesDTO rcvHeadersProfilesDTO = new RcvHeadersProfilesDTO();
		BeanUtils.copyProperties(rcvHeadersProfiles, rcvHeadersProfilesDTO);
		return rcvHeadersProfilesDTO;
	}

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

	@Override
	public Object edit(String pkId, RcvHeadersProfilesDTO rcvHeadersProfilesDTO) {
		UserDTO userDTO = userUtils.getUserDTO();
		super.vaildateModel(rcvHeadersProfilesDTO, true, userDTO, 0, validator, serviceEditMsg);
		RcvHeadersProfiles rcvHeadersProfiles = new RcvHeadersProfiles();
		BeanUtils.copyProperties(rcvHeadersProfilesDTO, rcvHeadersProfiles);
		this.setBaseSysField(rcvHeadersProfiles, true, userDTO);
		this.mapper.updateWithValidate(rcvHeadersProfiles,
				p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
		return rcvHeadersProfiles.getRcvHeaderId();
	}

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

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

	@Override
	public Page<RcvHeadersProfilesDTO> findList(RcvHeadersProfilesDTO rcvHeadersProfilesDTO, PageParam pageParam) {
		Criteria criteria = Criteria.forClass(RcvHeadersProfiles.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();
			RcvHeadersProfilesDTO condition = rcvHeadersProfilesDTO;
			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<RcvHeadersProfiles> list = this.mapper.findByCriteria(criteria);
		List<RcvHeadersProfilesDTO> collect = Optional.ofNullable(list).orElse(Collections.emptyList()).stream()
				.map(p -> {
					RcvHeadersProfilesDTO target = new RcvHeadersProfilesDTO();
					BeanUtils.copyProperties(p, target);
					return target;
				}).collect(Collectors.toList());
		Page<RcvHeadersProfiles> page = PageUtils.getPage(list);
		Page<RcvHeadersProfilesDTO> 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<RcvHeadersProfilesDTO> rcvHeadersProfilesDTOList) {
		// TODO
		UserDTO userDTO = userUtils.getUserDTO();
		for (RcvHeadersProfilesDTO rcvHeadersProfilesDTO : rcvHeadersProfilesDTOList) {
			RcvHeadersProfiles rcvHeadersProfiles = new RcvHeadersProfiles();
			BeanUtils.copyProperties(rcvHeadersProfilesDTO, rcvHeadersProfiles);
			this.vaildateModel(rcvHeadersProfiles, false, userDTO);
			this.buildField(rcvHeadersProfiles, false, userDTO);
			this.mapper.save(rcvHeadersProfiles);
		}
		return "";
	}

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

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

	private void vaildateModel(RcvHeadersProfiles rcvHeadersProfiles, Boolean editFlag, UserDTO userDTO) {

		if (!editFlag) {
		} else {
			// TODO
		}
	}

	private void buildField(RcvHeadersProfiles rcvHeadersProfiles, Boolean editFlag, UserDTO userDTO) {
		buildField(rcvHeadersProfiles, editFlag, userDTO, new Date());
	}

	private void buildField(RcvHeadersProfiles rcvHeadersProfiles, Boolean editFlag, UserDTO userDTO, Date now) {
		// 构建基础字段
		Date gmtCreate = rcvHeadersProfiles.getGmtCreate();
		Date gmtModified = rcvHeadersProfiles.getGmtModified();
		String creator = rcvHeadersProfiles.getCreator();
		String creatorName = rcvHeadersProfiles.getCreatorName();
		String modifier = rcvHeadersProfiles.getModifier();
		String modifierName = rcvHeadersProfiles.getModifierName();
		String enterpriseId = rcvHeadersProfiles.getEnterpriseId();

		String id = userDTO.getId();
		String username = userDTO.getUsername();
		String enterpriseId2 = userDTO.getEnterpriseId();
		if (ObjectUtils.isNull(now))
			now = new Date();
		if (!editFlag) {
			// 新增
			if (ObjectUtils.isNull(creator))
				rcvHeadersProfiles.setCreator(id);
			if (ObjectUtils.isNull(creatorName))
				rcvHeadersProfiles.setCreatorName(username);
			if (ObjectUtils.isNull(gmtCreate))
				rcvHeadersProfiles.setGmtCreate(now);
			if (ObjectUtils.isNull(enterpriseId)) {
				rcvHeadersProfiles.setEnterpriseId(enterpriseId2);
			}
		}
		// 编辑+新增
		if (ObjectUtils.isNull(modifier))
			rcvHeadersProfiles.setModifier(id);
		if (ObjectUtils.isNull(modifierName))
			rcvHeadersProfiles.setModifierName(username);
		if (ObjectUtils.isNull(gmtModified))
			rcvHeadersProfiles.setGmtModified(now);
		// 重复校验
		vaildateModelRepeated(rcvHeadersProfiles, editFlag, userDTO);
	}

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

	private boolean canEdit(String pkId) {
		boolean flag = true;
		RcvHeadersProfiles rcvHeadersProfiles = this.findById(pkId);
		AssertUtils.notNull(rcvHeadersProfiles, "收货拓展为空!");
		// TODO
		if (true)
			flag = false;
		return flag;
	}

	private Restriction buildCondition(RcvHeadersProfilesDTO rcvHeadersProfilesDTO) {
		// TODO
		return null;
	}

	@Override
	public List<RcvHeadersProfilesDTO> findByPKIdList(List<String> hidList) {
		// 根据主键id集合查询
		if (ObjectUtils.isNull(hidList))
			return null;
		String[] array = hidList.toArray(new String[hidList.size()]);
		List<RcvHeadersProfiles> list = this.mapper.findByIds(RcvHeadersProfiles.class, array, null);
		List<RcvHeadersProfilesDTO> collect = Optional.ofNullable(list).orElse(Collections.emptyList()).stream()
				.map(p -> {
					RcvHeadersProfilesDTO target = new RcvHeadersProfilesDTO();
					BeanUtils.copyProperties(p, target);
					return target;
				}).collect(Collectors.toList());
		return collect;
	}

}
