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

import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.search.SearchService;
import com.uas.platform.b2b.service.SaleARCheckService;
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.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.CollectionUtils;
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.*;

@Service
public class SaleARCheckServiceImpl implements SaleARCheckService {

	@Autowired
	private SaleARCheckItemDao saleARCheckItemDao;

	@Autowired
	private SaleARCheckDao saleARCheckDao;

	@Autowired
	private SaleARCheckReplyDao saleARCheckReplyDao;

	@Autowired
	private SearchService searchService;

	@Override
	public void save(List<SaleARCheckItem> checkItems) {
		saleARCheckItemDao.save(checkItems);
	}

	@Override
	public Page<SaleARCheck> findAllByPageInfo(final PageInfo pageInfo, final String keyword,
			final SearchFilter searchFilter) {
		return saleARCheckDao.findAll(new Specification<SaleARCheck>() {
			@Override
            public Predicate toPredicate(Root<SaleARCheck> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				if (searchFilter != null) {
					if (!CollectionUtils.isEmpty(searchFilter.getDistribute())) {
                        pageInfo.expression(PredicateUtils.in("vendUU", searchFilter.getDistribute(), false));
                    }
				}
				if (StringUtils.hasText(keyword)) {
					List<Object> lists = new ArrayList<>();
					PageParams pageParams = new PageParams();
					ModelMap map = new ModelMap();
					map.put("sac_enuu", SystemSession.getUser().getEnterprise().getUu());
					pageParams.setFilters(map);
					for (SaleARCheck list : searchService.searchSaleARCheckIds(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 SaleARCheck findById(Long id) {
		return saleARCheckDao.findOne(id);
	}

	@Override
	public void reply(List<SaleARCheckReply> replies) {
		if (!CollectionUtils.isEmpty(replies)) {
			for (SaleARCheckReply reply : replies) {
				reply(reply, false, false);
			}
		}
	}

	@Override
	public SaleARCheckReply reply(SaleARCheckReply reply, boolean agreed, boolean isB2b) {
		SaleARCheckItem item = saleARCheckItemDao.findOne(reply.getItemId());
		if (item == null) {
            throw new IllegalArgumentException();
        }
		reply.setDate(new Date());
		if (isB2b) {// 客户从B2B回复
			reply.setDate(new Date());
			reply.setRecorder(SystemSession.getUser().getUserName());
			reply.setType("c");
			reply.setSendStatus((short) Status.NOT_UPLOAD.value());
			if (agreed) {
				reply.setQty(item.getQty());
				reply.setRemark("确认对账数量");
				item.setReplyQty(item.getQty());// 明细的客户回复数量 = 明细的数量
				item.setAgreed(Constant.YES);
			} else {
				item.setReplyQty(reply.getQty());// 明细的客户回复数量 = 本次回复的数量
				if (item.getQty().equals(item.getReplyQty())) {// 本次回复数量 == 对账数量
					item.setAgreed(Constant.YES);// 明细已同意
				} else {
					item.setAgreed(Constant.NO);// 明细不同意
					item.setWaiting(Constant.YES);// 不同意的，需等到供应商确认数量
				}
			}
			item.setStatus((short) Status.REPLIED.value());
			item.getArCheck().setStatus((short) Status.REPLIED.value());// 主记录状态设为200
			List<SaleARCheckReply> replies = saleARCheckReplyDao.findByItemId(reply.getItemId());
			if (CollectionUtils.isEmpty(replies)) {// 之前没有回复，把明细当做一条供应商的回复保存
				SaleARCheckReply arReply = new SaleARCheckReply();
				arReply.setDate(item.getArCheck().getDate());
				arReply.setItemId(item.getId());
				arReply.setQty(item.getQty());
				arReply.setRemark("对账单原始数量");
				arReply.setSendStatus((short) Status.DOWNLOADED.value());
				arReply.setType("v");
				saleARCheckReplyDao.save(arReply);
			}
		} else {// 供应商回复
			reply.setType("v");
			reply.setSendStatus((short) Status.DOWNLOADED.value());
			item.setWaiting(null);// 供应商已确认，不需要等待
			item.setQty(reply.getQty());// 明细的供应商对账数量 = 本次回复的数量
			// 重新计算明细的对账金额
			item.setAmount(
					(reply.getQty() == null ? 0 : reply.getQty()) * (item.getPrice() == null ? 0 : item.getPrice()));
			if (item.getQty().equals(item.getReplyQty())) {// 本次回复数量 == 对账数量
				item.setAgreed(Constant.YES);// 明细已同意
				item.setStatus((short) Status.REPLIED.value());
			} else {
				item.setAgreed(Constant.NO);// 明细不同意
				item.setStatus((short) Status.NOT_REPLY.value());
			}
		}
		item = saleARCheckItemDao.save(item);
		reply = saleARCheckReplyDao.save(reply);
		reply.setItem(item);
		updateCheckStatus(item.getArCheck().getId());
		return reply;
	}

	/**
	 * 修改主记录的同意数和不同意数
	 * 
	 * @param id
	 *            对账单id
	 */
	private void updateCheckStatus(Long id) {
		SaleARCheck check = saleARCheckDao.findOne(id);
		if (check == null) {
            throw new IllegalArgumentException();
        }
		int agree = saleARCheckItemDao.findAgreedCountBycheckId(id);
		int disagree = saleARCheckItemDao.findDisAgreedCountBycheckId(id);
		check.setAgree(agree);
		check.setDisagree(disagree);
		saleARCheckDao.save(check);
	}

	@Override
	public List<SaleARCheckReply> getReplies(Long itemId) {
		return saleARCheckReplyDao.findByItemId(itemId);
	}

	@Override
	public List<SaleARCheckReply> getUploadReply() {
		return saleARCheckReplyDao.findByVendUUAndStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void uploadReplySuccess(String[] ids) {
		if (ids.length > 0) {
			for (String id : ids) {
				SaleARCheckReply reply = saleARCheckReplyDao.findOne(Long.parseLong(id));
				reply.setSendStatus((short) Status.DOWNLOADED.value());
				saleARCheckReplyDao.save(reply);
			}
		}
	}

}
