package com.uas.platform.b2b.service.impl;

import com.uas.platform.b2b.dao.PurchaseOrderItemDao;
import com.uas.platform.b2b.dao.PurchaseReturnDao;
import com.uas.platform.b2b.dao.PurchaseReturnItemDao;
import com.uas.platform.b2b.erp.model.OrderDetailPrice;
import com.uas.platform.b2b.erp.model.ProdInOutRefreshPrice;
import com.uas.platform.b2b.erp.service.PurchaseService;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.search.SearchService;
import com.uas.platform.b2b.service.PurchaseReturnService;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.core.model.Constant;
import com.uas.platform.core.model.PageInfo;
import com.uas.platform.core.model.Status;
import com.uas.platform.core.persistence.criteria.PredicateUtils;
import com.uas.search.b2b.model.PageParams;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
public class PurchaseReturnServiceImpl implements PurchaseReturnService {

	@Autowired
	private PurchaseReturnItemDao purchaseReturnItemDao;

	@Autowired
	private PurchaseReturnDao purchaseReturnDao;

	@Autowired
	private PurchaseOrderItemDao purchaseOrderItemDao;

	@Autowired
	private SearchService searchService;

    @Autowired
    private PurchaseService purchaseService;

    @Override
	public void save(List<PurchaseReturnItem> returnItems) {
		returnItems = purchaseReturnItemDao.save(returnItems);
		// 关联订单的验退数量
		for (PurchaseReturnItem returnItem : returnItems) {
			if (returnItem.getOrderItemId() != null) {
				PurchaseOrderItem orderItem = purchaseOrderItemDao.findOne(returnItem.getOrderItemId());
				if (null != orderItem) {
					orderItem.setReturnQty((orderItem.getReturnQty() == null ? 0 : orderItem.getReturnQty())
							+ returnItem.getQty());
					purchaseOrderItemDao.save(orderItem);
				}
			}
		}
	}

	@Override
	public List<PurchaseReturn> findNotUpload() {
		return purchaseReturnDao.findByVendUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onUploadSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseReturn return1 = purchaseReturnDao.findOne(Long.parseLong(id));
			if (return1 != null) {
				return1.setSendStatus((short) Status.DOWNLOADED.value());
				purchaseReturnDao.save(return1);
			}
		}
	}

	@Override
	public Page<PurchaseReturn> findAllByPageInfo(final PageInfo pageInfo, final String keyword,
			final SearchFilter filter) {
		return purchaseReturnDao.findAll(new Specification<PurchaseReturn>() {

			@Override
            public Predicate toPredicate(Root<PurchaseReturn> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				if (filter != null) {
					if (!CollectionUtils.isEmpty(filter.getDistribute())) {
                        pageInfo.expression(PredicateUtils.in("enUU", filter.getDistribute(), false));
                    }
				}
				if (StringUtils.hasText(keyword)) {
					List<Object> lists = new ArrayList<>();
					PageParams pageParams = new PageParams();
					ModelMap map = new ModelMap();
					map.put("pr_veduu", SystemSession.getUser().getEnterprise().getUu());
					pageParams.setFilters(map);
					for (PurchaseReturn list : searchService.searchPurchaseReturnIds(keyword, pageParams)
							.getContent()) {
						lists.add(list.getId());
					}
					pageInfo.expression(PredicateUtils.in("id", lists, false));
				}
				query.where(pageInfo.getPredicates(root, query, builder));
				return null;
			}
		}, pageInfo);
	}

	@Override
	public PurchaseReturn findById(Long id) {
		return purchaseReturnDao.findOne(id);
	}

	@Override
	public void nonPosting(List<PurchaseReturn> purchaseReturns) {
		if (!CollectionUtils.isEmpty(purchaseReturns)) {
			for (PurchaseReturn purchaseReturn : purchaseReturns) {
				if (purchaseReturn.getSendStatus() == Status.DOWNLOADED.value()) {
					// 已传输到供应商ERP，修改单据反过账状态
					purchaseReturn.setNonPosting(Constant.YES);
					purchaseReturnDao.save(purchaseReturn);
				} else {
					// 未传输到供应商ERP，直接删除平台上的单据
					purchaseReturnDao.delete(purchaseReturn);
				}
				// 关联订单的验退数量
				if (!CollectionUtils.isEmpty(purchaseReturn.getReturnItems())) {
					for (PurchaseReturnItem returnItem : purchaseReturn.getReturnItems()) {
						PurchaseOrderItem orderItem = purchaseOrderItemDao.findOne(returnItem.getOrderItemId());
						if (null != orderItem) {
							// 已接受数未空或小于本次验收单数目，设为0
							if (orderItem.getReturnQty() == null || orderItem.getReturnQty() < returnItem.getQty()) {
								orderItem.setReturnQty((double) 0);
							} else {// 否则减去本次的验收数量
								orderItem.setReturnQty(orderItem.getReturnQty() - returnItem.getQty());
							}
							purchaseOrderItemDao.save(orderItem);
						}
					}
				}
			}
		}
	}

	@Override
	public List<PurchaseReturn> getNonPosting() {
		return purchaseReturnDao.findByVendUUAndNonPosting(SystemSession.getUser().getEnterprise().getUu(),
				Constant.YES);
	}

	@Override
	public void onNonPostingUploadSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseReturn purchaseReturn = purchaseReturnDao.findOne(Long.parseLong(id));
			if (purchaseReturn != null) {
				purchaseReturnDao.delete(purchaseReturn);
			}
		}
	}

	@Override
	public List<PurchaseReturnItem> convertPirceForProdIn(List<ProdInOutRefreshPrice> prodInOuts) {
		List<PurchaseReturnItem> items = new ArrayList<PurchaseReturnItem>();
		List<OrderDetailPrice> detailPriceList = new ArrayList<>();
		if (!CollectionUtils.isEmpty(prodInOuts)) {
			for (ProdInOutRefreshPrice prod : prodInOuts) {
				PurchaseReturnItem returnItem = purchaseReturnItemDao.findByEnUUAndCodeAndNumber(
						SystemSession.getUser().getEnterprise().getUu(), prod.getPbu_inoutno(), prod.getPbu_pdno());
				if (null != returnItem) {
					returnItem.setOrderPrice(prod.getPbu_orderprice());
					returnItem.setTaxrate(prod.getPbu_taxrate());
					items.add(returnItem);
					if (null != returnItem.getOrderItemId()) {
						detailPriceList.add(new OrderDetailPrice(returnItem.getOrderItemId(), returnItem.getOrderPrice(), returnItem.getTaxrate()));
					}
				}
			}
		}
		if (!CollectionUtils.isEmpty(detailPriceList)) {
		    purchaseService.refreshPrice(detailPriceList, OrderType.salereturn.name());
        }
		return items;
	}
}
