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

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

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 com.uas.platform.b2b.dao.PurchaseNoticeDao;
import com.uas.platform.b2b.dao.SaleSendDao;
import com.uas.platform.b2b.dao.SaleSendItemDao;
import com.uas.platform.b2b.erp.model.PurchaseNotify;
import com.uas.platform.b2b.model.PurchaseNotice;
import com.uas.platform.b2b.model.PurchaseOrder;
import com.uas.platform.b2b.model.SaleSend;
import com.uas.platform.b2b.model.SaleSendItem;
import com.uas.platform.b2b.service.PurchaseNoticeService;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.b2b.support.XingePusher;
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;

@Service
public class PurchaseNoticeServiceImpl implements PurchaseNoticeService {

	@Autowired
	private PurchaseNoticeDao purchaseNoticeDao;

	@Autowired
	private SaleSendDao saleSendDao;

	@Autowired
	private SaleSendItemDao saleSendItemDao;

	@Override
	public void save(List<PurchaseNotice> notices) {
		purchaseNoticeDao.save(notices);
		// 将送货提醒推送通知供应商联系人UU号
		for (PurchaseNotice notice : notices) {
			PurchaseOrder order = notice.getOrderItem().getOrder();
			if (order.getVendUserUU() != null) {
				// Android
				XingePusher.pushSingleAccountAndroid(order.getVendUserUU().toString(), "新增一个送货提醒-", "客户采购单号:" + order.getCode() + ",客户:"
						+ order.getEnterprise().getEnName(), "com.sas.mobile.activity.PurchaseChangeActivity");
				// IOS
				XingePusher.pushSingleAccountIOS(order.getVendUserUU().toString(), "新增一个送货提醒-" + "客户采购单号:" + order.getCode() + ",客户:"
						+ order.getEnterprise().getEnName());
			}
		}
	}

	@Override
	public Page<PurchaseNotice> findAllByPageInfo(final PageInfo pageInfo) {
		return purchaseNoticeDao.findAll(new Specification<PurchaseNotice>() {

			public Predicate toPredicate(Root<PurchaseNotice> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				query.where(pageInfo.getPredicates(root, query, builder));
				return null;
			}
		}, pageInfo);
	}

	@Override
	public Page<PurchaseNotice> findDoneByPageInfo(final PageInfo pageInfo) {
		return purchaseNoticeDao.findAll(new Specification<PurchaseNotice>() {

			public Predicate toPredicate(Root<PurchaseNotice> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				pageInfo.filter("status", Status.REPLIED.value());
				pageInfo.expression(PredicateUtils.or(PredicateUtils.isNull("end"), PredicateUtils.ne("end", Constant.YES, false)));
				query.where(pageInfo.getPredicates(root, query, builder));
				return null;
			}
		}, pageInfo);
	}

	@Override
	public PurchaseNotice findById(Long id) {
		return purchaseNoticeDao.findOne(id);
	}

	@Override
	public void send(List<SaleSendItem> sendItems) {
		saleSendItemDao.save(sendItems);
		for (SaleSendItem item : sendItems)
			purchaseNoticeDao.updateBySend(item.getNoticeId());
	}

	@Override
	public List<SaleSendItem> findSendById(long noticeId) {
		return saleSendItemDao.findByNoticeId(noticeId);
	}

	@Override
	public List<PurchaseNotice> findNotUploadNotice() {
		return purchaseNoticeDao.findByVendUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onNoticeDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseNotice notice = purchaseNoticeDao.findOne(Long.parseLong(id));
			if (notice != null) {
				notice.setSendStatus((short) Status.DOWNLOADED.value());
				purchaseNoticeDao.save(notice);
			}
		}
	}

	@Override
	public List<SaleSend> findNotUploadSend() {
		return saleSendDao.findByCustUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(), (short) Status.NOT_UPLOAD.value());
	}

	@Override
	public List<SaleSend> findNotSendSend() {
		return saleSendDao.findByEnUUAndBackStatus(SystemSession.getUser().getEnterprise().getUu(), (short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onSendUploadSuccess(String[] idArray) {
		for (String id : idArray) {
			SaleSend send = saleSendDao.findOne(Long.parseLong(id));
			if (send != null) {
				send.setSendStatus((short) Status.DOWNLOADED.value());
				saleSendDao.save(send);
			}
		}
	}

	@Override
	public void onSendDownSuccess(String[] idArray) {
		for (String id : idArray) {
			SaleSend send = saleSendDao.findOne(Long.parseLong(id));
			if (send != null) {
				send.setBackStatus((short) Status.DOWNLOADED.value());
				saleSendDao.save(send);
			}
		}
	}

	@Override
	public void end(List<PurchaseNotify> notifies) {
		long enUU = SystemSession.getUser().getEnterprise().getUu();
		for (PurchaseNotify notify : notifies) {
			List<PurchaseNotice> notices = purchaseNoticeDao.findByEnUUAndSourceId(enUU, notify.getPn_id());
			if (!CollectionUtils.isEmpty(notices)) {
				PurchaseNotice notice = notices.get(0);
				notice.setEnd(Constant.YES);
				notice.setEndStatus((short) Status.NOT_UPLOAD.value());
				purchaseNoticeDao.save(notice);
				// 推送结案送回提醒给采购单供应商联系人
				Long vendUserUU = notice.getOrderItem().getOrder().getVendUserUU();
				if (vendUserUU != null) {
					XingePusher.pushSingleAccountAndroid(vendUserUU.toString(), "客户取消了送货提醒", "物料:"
							+ notice.getOrderItem().getProduct().getTitle() + " - " + notice.getOrderItem().getOrder().getCode(), null);
					XingePusher.pushSingleAccountIOS(vendUserUU.toString(), "客户取消了送货提醒 - " + "物料:"
							+ notice.getOrderItem().getProduct().getTitle());
				}
			}
		}
	}

	@Override
	public List<PurchaseNotice> findNotSendEnd() {
		return purchaseNoticeDao.findByVendUUAndEndStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onEndDownSuccess(String[] idArray) {
		for (String id : idArray) {
			PurchaseNotice notice = purchaseNoticeDao.findOne(Long.parseLong(id));
			if (notice != null) {
				notice.setEndStatus((short) Status.DOWNLOADED.value());
				purchaseNoticeDao.save(notice);
			}
		}
	}

	@Override
	public void send(Long noticeId, SaleSend send) {
		PurchaseNotice notice = purchaseNoticeDao.findOne(noticeId);
		if (notice != null) {
			double thisQty = 0;
			for (SaleSendItem item : send.getSendItems())
				thisQty += item.getQty();
			double endQty = (notice.getEndQty() == null ? 0.0 : notice.getEndQty()) + thisQty;
			if (endQty > notice.getQty())
				throw new IllegalArgumentException("累计发货数量将超出本次送货提醒的需求数！");
			PurchaseOrder order = notice.getOrderItem().getOrder();
			send.setCurrency(order.getCurrency());
			send.setBackStatus((short) Status.NOT_UPLOAD.value());
			send.setSendStatus((short) Status.NOT_UPLOAD.value());
			send.setCustUU(notice.getEnUU());
			send.setCustUserUU(order.getUserUU());
			send.setEnUU(SystemSession.getUser().getEnterprise().getUu());
			send.setPayments(order.getPayments());
			send.setRate(order.getRate());
			short number = 0;
			for (SaleSendItem item : send.getSendItems()) {
				item.setNoticeId(noticeId);
				item.setNotice(notice);
				item.setNumber(++number);
				item.setPrice(notice.getOrderItem().getPrice());
				item.setSend(send);
			}
			saleSendItemDao.save(send.getSendItems());
			notice.setEndQty(endQty);
			notice.setStatus((short) (endQty == notice.getQty() ? Status.REPLIED.value() : Status.NOT_REPLY.value()));
			purchaseNoticeDao.save(notice);
		}
	}

	@Override
	public int getOnhandCount() {
		return purchaseNoticeDao.getCountByVendUUAndStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_REPLY.value());
	}

}
