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

import com.uas.platform.b2b.core.util.ContextUtils;
import com.uas.platform.b2b.core.util.ThreadTask;
import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.event.MakeOrderSaveReleaseEvent;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.service.MakeOrderService;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.b2b.support.XingePusher;
import com.uas.platform.core.exception.IllegalOperatorException;
import com.uas.platform.core.model.Constant;
import com.uas.platform.core.model.PageInfo;
import com.uas.platform.core.model.Status;
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.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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 MakeOrderServiceImpl implements MakeOrderService {

	@Autowired
	private MakeOrderDao makeOrderDao;

	@Autowired
	private MakeOrderReplyDao makeOrderReplyDao;

	@Autowired
	private UserBaseInfoDao userBaseInfoDao;

	@Autowired
	private UserOrderDao userOrderDao;

	@Autowired
	private DistributeDao distributeDao;

	@Autowired
	private  RoleDao roleDao;

	@Autowired
	private  UserDao userDao;

	@Autowired
	private VendorDao vendorDao;

	@Override
	public Page<MakeOrder> findAllByPageInfo(final PageInfo pageInfo, String keyword) {
		return makeOrderDao.findAll(new Specification<MakeOrder>() {
			@Override
            public Predicate toPredicate(Root<MakeOrder> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				return query.where(pageInfo.getPredicates(root, query, builder)).getRestriction();
			}
		}, pageInfo);
	}

	@Override
	public List<MakeOrder> findNotUploadOrder() {
		return makeOrderDao.findByVendUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void saveOrders(List<MakeOrder> orders) {
		List<MakeOrder> newOrders = makeOrderDao.save(orders);
		saveUserOrders(orders);
		// 结案委外单也用了这个方法，所以需要判断
		List<MakeOrder> makeOrders = new ArrayList<>();
		for (MakeOrder order : newOrders) {
			if (order.getEnd() != 1) {
				makeOrders.add(order);
			}
		}
		ContextUtils.publishEvent(new MakeOrderSaveReleaseEvent(makeOrders));
	}

	private void saveUserOrders(final List<MakeOrder> orders) {

		ThreadTask.getInstance().execute(new Runnable() {
			@Override
			public void run() {
            	/* 添加供应商的阅读记录*/
				for(MakeOrder order : orders) {
					Set<Long> userUUs = new HashSet<>();
					// 添加管理员
					List<Role> roles = roleDao.findByEnUUAndIssys(order.getVendUU(), Constant.YES);
					if (!CollectionUtils.isEmpty(roles)) {
						List<User> admins = userDao.findByRole(roles.get(0).getId());
						for (User admin : admins) {
							if (!userUUs.contains(admin.getUserUU())) {
								userUUs.add(admin.getUserUU());
							}
						}
					}
					List<Vendor> vendors = vendorDao.findByMyEnUUAndVendUU(order.getEnUU(), order.getVendUU());
					// 查找有权限的用户
					if (!CollectionUtils.isEmpty(vendors)) {
						Long vendorId = vendors.get(0).getId();
						List<Distribute> distributes = distributeDao.findByVendorId(vendorId);
						if (!CollectionUtils.isEmpty(distributes)) {
							for (Distribute distribute : distributes) {
								if (!userUUs.contains(distribute.getUserUU())) {
									userUUs.add(distribute.getUserUU());
								}
							}
						}
					}
					UserOrders userOrders;
					List<UserOrders> list = new ArrayList<>();
					for (Long userUU : userUUs) {
						if (userUU == null) {
							continue;
						}
						userOrders = new UserOrders(userUU, order.getVendUU(), order.getId(), "sale", "make$orders");
						list.add(userOrders);
					}

                	/* 添加采购员的阅读记录*/
					if (order.getUserUU() != null) {
						userOrders = new UserOrders(order.getUserUU(), order.getEnUU(), order.getId(), "purc", "make$orders");
						userOrders.setReadStatus((short) Status.READ.value());
                        list.add(userOrders);
					}
					userOrderDao.save(list);
				}
			}
		});
	}

	@Override
	public void onMakeDownSuccess(String[] idArray) {
		for (String id : idArray) {
			MakeOrder order = makeOrderDao.findOne(Long.parseLong(id));
			if (order != null) {
				order.setSendStatus((short) Status.DOWNLOADED.value());
				makeOrderDao.save(order);
			}
		}
	}

	@Override
	public MakeOrderReply reply(MakeOrderReply reply) {
		return reply(reply, true);
	}

	@Override
	public List<MakeOrderReply> reply(List<MakeOrderReply> replies) {
		List<MakeOrderReply> newReplies = new ArrayList<MakeOrderReply>();
		if (!CollectionUtils.isEmpty(replies)) {
			for (MakeOrderReply reply : replies) {
				newReplies.add(reply(reply, false));
			}
		}
		return newReplies;
	}

	/**
	 * @param reply
	 * @param isB2b
	 *            是否b2b新增
	 */
	@Transactional
	private MakeOrderReply reply(MakeOrderReply reply, boolean isB2b) {
		if (isB2b) {
			reply.setDate(new Date());
			// 作为B2B->买家ERP数据是否已传输的标志--未传输
			reply.setSendStatus((short) Status.NOT_UPLOAD.value());
			// 作为B2B->卖家ERP数据是否已传输的标志--未传输
			reply.setBackStatus((short) Status.NOT_UPLOAD.value());
			reply.setRecorder(SystemSession.getUser().getUserName());
			reply.setType("供应商平台回复");
		}
		MakeOrder order = makeOrderDao.findOne(reply.getOrderId());
		if (order == null) {
            throw new IllegalOperatorException("不能对无效的委外加工单回复");
        }
		Double replyQty = order.getReplyQty();
		replyQty = replyQty == null ? 0 : replyQty;
		order.setReplyQty(replyQty + reply.getQty());
		if (order.getReplyQty() > order.getQty()) {
            throw new IllegalOperatorException("回复的数量合计超过了订单数量");
        }
		if (order.getReplyQty() < 0) {
            throw new IllegalOperatorException("回复的数量合计不能为负数");
        }
		reply.setOrder(order);
		reply = makeOrderReplyDao.save(reply);
		makeOrderDao.updateByReply(reply.getDelivery(), reply.getRemark(), order.getId());
		// 委外加工单回复状态
		order = makeOrderDao.findOne(reply.getOrderId());
		if (order.getReplyQty() >= order.getQty()) {
			order.setStatus((short) Status.REPLIED.value());
		} else {
			order.setStatus((short) Status.NOT_REPLY.value());
		}
		makeOrderDao.save(order);
		// 将回复信息推送给采购企业采购员（或管理员）
		if (order.getUserUU() != null) {
			UserBaseInfo user = userBaseInfoDao.findOne(order.getUserUU());
			XingePusher.pushByUser(user, "委外加工单收到供应商回复", "订单编号:" + order.getCode(), "", "");
		}
		return reply;
	}

	@Override
	public List<MakeOrderReply> findNotBackReply() {
		return makeOrderReplyDao.findByOrderVendUUAndBackStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public List<MakeOrderReply> findNotSendReply() {
		return makeOrderReplyDao.findByOrderEnUUAndSendStatus(SystemSession.getUser().getEnterprise().getUu(),
				(short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onReplyBackSuccess(String[] idArray) {
		for (String id : idArray) {
			MakeOrderReply reply = makeOrderReplyDao.findOne(Long.parseLong(id));
			if (reply != null) {
				reply.setBackStatus((short) Status.DOWNLOADED.value());
				makeOrderReplyDao.save(reply);
			}
		}
	}

	@Override
	public void onReplySendSuccess(String[] idArray) {
		for (String id : idArray) {
			MakeOrderReply reply = makeOrderReplyDao.findOne(Long.parseLong(id));
			if (reply != null) {
				reply.setSendStatus((short) Status.DOWNLOADED.value());
				makeOrderReplyDao.save(reply);
			}
		}
	}

	@Override
	public MakeOrder findById(Long id) {
		return makeOrderDao.findOne(id);
	}

	@Override
	public void print(Long id) {
		MakeOrder order = makeOrderDao.findOne(id);
		if (order != null) {
			order.setPrint((short) ((order.getPrint() == null ? 0 : order.getPrint()) + 1));
		}
		makeOrderDao.save(order);
	}

	@Override
	public List<MakeOrder> findNotSendEnd() {
		long enUU = SystemSession.getUser().getEnterprise().getUu();
		return makeOrderDao.findByVendUUAndEndSendStatus(enUU, (short) Status.NOT_UPLOAD.value());
	}

	@Override
	public void onEndDownSuccess(String[] ids) {
		for (String id : ids) {
			MakeOrder order = makeOrderDao.findOne(Long.parseLong(id));
			if (order != null) {
				order.setEndSendStatus((short) Status.DOWNLOADED.value());
				makeOrderDao.save(order);
			}
		}
	}

}
