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

import com.uas.platform.b2b.core.util.StringUtil;
import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.erp.exception.ExceptionNote;
import com.uas.platform.b2b.erp.model.OrderDetailPrice;
import com.uas.platform.b2b.erp.model.ProdInOutRefreshPrice;
import com.uas.platform.b2b.erp.model.PurchaseProdInOut;
import com.uas.platform.b2b.erp.service.PurchaseProdInOutService;
import com.uas.platform.b2b.erp.service.PurchaseService;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.ps.ProductUtils;
import com.uas.platform.b2b.service.NotExistOrderService;
import com.uas.platform.b2b.support.SystemSession;
import org.apache.axis.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;


@Service
public class PurchaseProdInOutServiceImpl implements PurchaseProdInOutService {

	@Autowired
	private PurchaseOrderItemDao purchaseOrderItemDao;

	@Autowired
	private PurchaseAcceptDao purchaseAcceptDao;

	@Autowired
	private PurchaseAcceptItemDao purchaseAcceptItemDao;

	@Autowired
	private PurchaseReturnDao purchaseReturnDao;

	@Autowired
	private PurchaseBadInDao purchaseBadInDao;

	@Autowired
	private PurchaseBadOutDao purchaseBadOutDao;

	@Autowired
	private EnterpriseDao enterpriseDao;

	@Autowired
	private ProductDao productDao;

	@Autowired
	private NotExistOrderService orderService;

	@Autowired
    private PurchaseService purchaseService;

	@Override
	public List<PurchaseAcceptItem> convertProdInOuts(List<PurchaseProdInOut> prodInOuts) throws Exception {
		List<PurchaseAcceptItem> acceptItems = new ArrayList<PurchaseAcceptItem>();
		long enUU = SystemSession.getUser().getEnterprise().getUu();
		for (PurchaseProdInOut prodInOut : prodInOuts) {
			PurchaseAccept accept = prodInOut.convent();
			List<PurchaseAccept> accepts2 = purchaseAcceptDao.findByEnUUAndCode(enUU, accept.getCode());
			Enterprise vendor = enterpriseDao.findEnterpriseByUu(accept.getVendUU());
			// 采购验收单不存在，供应商UU号存在对应供应商
			if (accepts2.size() == 0 && vendor != null) {
				// 设置明细对应的采购单明细
                List<NotExistOrders> ordersList = new ArrayList<>();
                String sign = "";
				for (Iterator<PurchaseAcceptItem> it = accept.getAcceptItems().iterator(); it.hasNext();) {
					PurchaseAcceptItem item = it.next();
					if (item.getOrderItem() != null) {
						List<PurchaseOrderItem> purchaseOrderItems = purchaseOrderItemDao
								.findByEnUUAndOrderCodeAndNumber(enUU, item.getOrderItem().getOrder().getCode(),
										item.getOrderItem().getNumber());
						// 对应的采购单存在
						if (purchaseOrderItems.size() > 0) {
							// 对应的采购单明细set进去
							item.setOrderItem(purchaseOrderItems.get(0));
							item.setOrderItemId(purchaseOrderItems.get(0).getId());
							// 设置主记录
							item.setAccept(accept);
							item.setErpDate(new Date());
							item.setProdcode(purchaseOrderItems.get(0).getProduct().getCode());
							item.setProdId(purchaseOrderItems.get(0).getProductId());
							acceptItems.add(item);
						} else {
							if (StringUtils.isEmpty(sign)) {
							    sign = StringUtil.uuid();
                            }
                            ordersList.add(new NotExistOrders(enUU, item.getOrderItem().getOrder().getCode(),
                                    com.uas.platform.b2b.temporary.model.OrderType.saleItem.name(), item.getOrderItem().getNumber(), sign));
						}
					} else {
						List<Product> prod = productDao.findByEnUUAndCode(enUU, item.getProdcode());
						if (prod.size() > 0) {
							item.setProduct(prod.get(0));
							item.setProdId(prod.get(0).getId());
						} else {
						    // 物料不存在先进行存储
							Product product = new Product();
							product.setCode(item.getProdcode());
							product.setEnUU(enUU);
							Long proId = ProductUtils.updateOne(product);
							item.setProdId(proId);
						}
						item.setAccept(accept);
						item.setErpDate(new Date());
						acceptItems.add(item);
					}
				}
				if (!CollectionUtils.isEmpty(ordersList)) {
				    orderService.batchSave(ordersList, ExceptionNote.SALEITEM_NOTFOUND.getPhrase(), sign);
                }
			} else if (accepts2.size() > 0 && vendor != null) {
				Set<PurchaseAcceptItem> haditems = accepts2.get(0).getAcceptItems();
				List<String> haditemsBatchCode = new ArrayList<String>();
				for (Iterator<PurchaseAcceptItem> itHaditems = haditems.iterator(); itHaditems.hasNext();) {
					PurchaseAcceptItem hadItem = itHaditems.next();
					haditemsBatchCode.add(hadItem.getBatchCode());
				}
				// 设置明细对应的采购单明细
				for (Iterator<PurchaseAcceptItem> it = accept.getAcceptItems().iterator(); it.hasNext();) {
					PurchaseAcceptItem item = it.next();
					if (haditemsBatchCode.contains(item.getBatchCode())) {
						//已上传的明细不要
						it.remove();
					} else {
						if (item.getOrderItem() != null) {
							List<PurchaseOrderItem> purchaseOrderItems = purchaseOrderItemDao
									.findByEnUUAndOrderCodeAndNumber(enUU, item.getOrderItem().getOrder().getCode(),
											item.getOrderItem().getNumber());
							// 对应的采购单存在
							if (purchaseOrderItems.size() > 0) {
								// 对应的采购单明细set进去
								item.setOrderItem(purchaseOrderItems.get(0));
								item.setOrderItemId(purchaseOrderItems.get(0).getId());
								// 设置主记录
								item.setAccept(accepts2.get(0));
								item.setErpDate(new Date());
								item.setProdcode(purchaseOrderItems.get(0).getProduct().getCode());
								item.setProdId(purchaseOrderItems.get(0).getProductId());
								acceptItems.add(item);
							} else {
								it.remove();
							}
						} else {
							List<Product> prod = productDao.findByEnUUAndCode(enUU, item.getProdcode());
							if (prod.size() > 0) {
								item.setProduct(prod.get(0));
								item.setProdId(prod.get(0).getId());
							} else {
								// 物料不存在先进行存储
								Product product = new Product();
								product.setCode(item.getProdcode());
								product.setEnUU(enUU);
								Long proId = ProductUtils.updateOne(product);
								item.setProduct(product);
								item.setProdId(proId);
							}
							item.setAccept(accepts2.get(0));
							item.setErpDate(new Date());
							acceptItems.add(item);
						}
					}
				}
			}
		}
		return acceptItems;
	}

	@Override
	public List<PurchaseReturnItem> convertReturns(List<PurchaseProdInOut> prodInOuts) throws Exception {
		List<PurchaseReturnItem> returnItems = new ArrayList<PurchaseReturnItem>();
		long enUU = SystemSession.getUser().getEnterprise().getUu();
		for (PurchaseProdInOut prodInOut : prodInOuts) {
			PurchaseReturn returnn = prodInOut.conventToReturn();
			List<PurchaseReturn> returns2 = purchaseReturnDao.findByEnUUAndCode(enUU, returnn.getCode());
			Enterprise vendor = enterpriseDao.findEnterpriseByUu(returnn.getVendUU());
			// 采购验收单不存在，供应商UU号存在对应供应商
			if (returns2.size() == 0 && vendor != null) {
				// 设置明细对应的采购单明细
				for (PurchaseReturnItem returnItem : returnn.getReturnItems()) {
					if (null != returnItem.getOrderDetno() && null != returnItem.getOrderCode()) {
						List<PurchaseOrderItem> purchaseOrderItems = purchaseOrderItemDao
								.findByEnUUAndOrderCodeAndNumber(enUU, returnItem.getOrderCode(), returnItem.getOrderDetno());
						// 对应的采购单存在
						if (purchaseOrderItems.size() > 0) {
							returnItem.setOrderItemId(purchaseOrderItems.get(0).getId());
							returnItem.setProdId(purchaseOrderItems.get(0).getProductId());
							returnItem.setProdCode(purchaseOrderItems.get(0).getProduct().getCode());
						}
					} else {
						List<Product> prod = productDao.findByEnUUAndCode(enUU, returnItem.getProdCode());
						if (prod.size() > 0) {
							returnItem.setProdId(prod.get(0).getId());
						} else {
							// 物料不存在先进行存储
							Product product = new Product();
							product.setCode(returnItem.getProdCode());
							product.setEnUU(enUU);
							Long proId = ProductUtils.updateOne(product);
							returnItem.setProdId(proId);
						}
					}
					// 设置主记录
					returnItem.setPurchaseReturn(returnn);
					returnItem.setErpDate(new Date());
					returnItems.add(returnItem);
				}
			}
		}
		return returnItems;
	}

	@Override
	public List<PurchaseBadInItem> convertBadIns(List<PurchaseProdInOut> prodInOuts) {
		List<PurchaseBadInItem> badInItems = new ArrayList<PurchaseBadInItem>();
		long enUU = SystemSession.getUser().getEnterprise().getUu();
		for (PurchaseProdInOut prodInOut : prodInOuts) {
			PurchaseBadIn badIn = prodInOut.conventToBadIn();
			List<PurchaseBadIn> badIns = purchaseBadInDao.findByEnUUAndCode(enUU, badIn.getCode());
			Enterprise vendor = enterpriseDao.findEnterpriseByUu(badIn.getVendUU());
			// 采购验收单不存在，供应商UU号存在对应供应商
			if (badIns.size() == 0 && vendor != null) {
                // 设置明细对应的采购单明细
				for (Iterator<PurchaseBadInItem> it = badIn.getBadInItems().iterator(); it.hasNext();) {
					PurchaseBadInItem badInItem = it.next();
					List<PurchaseOrderItem> purchaseOrderItems = purchaseOrderItemDao.findByEnUUAndOrderCodeAndNumber(
							enUU, badInItem.getOrderItem().getOrder().getCode(), badInItem.getOrderItem().getNumber());
                    // 对应的采购单存在
					if (purchaseOrderItems.size() > 0) {
                        // 对应的采购单明细set进去
						badInItem.setOrderItem(purchaseOrderItems.get(0));
						badInItem.setOrderItemId(purchaseOrderItems.get(0).getId());
                        // 设置主记录
						badInItem.setBadIn(badIn);
						badInItem.setErpDate(new Date(System.currentTimeMillis()));
						badInItems.add(badInItem);
					} else {
						it.remove();
					}
				}
			}
		}
		return badInItems;
	}

	@Override
	public List<PurchaseBadOutItem> convertBadOuts(List<PurchaseProdInOut> prodInOuts) {
		List<PurchaseBadOutItem> badOutItems = new ArrayList<PurchaseBadOutItem>();
		long enUU = SystemSession.getUser().getEnterprise().getUu();
		for (PurchaseProdInOut prodInOut : prodInOuts) {
			PurchaseBadOut badOut = prodInOut.conventToBadOut();
			List<PurchaseBadOut> badOuts = purchaseBadOutDao.findByEnUUAndCode(enUU, badOut.getCode());
			Enterprise vendor = enterpriseDao.findEnterpriseByUu(badOut.getVendUU());
			// 不良品出库单不存在，供应商UU号存在对应供应商
			if (badOuts.size() == 0 && vendor != null) {
				if (badOut.getBadOutItems() != null) {
                    // 设置明细对应的采购单明细
					for (Iterator<PurchaseBadOutItem> it = badOut.getBadOutItems().iterator(); it.hasNext();) {
						PurchaseBadOutItem badOutItem = it.next();
						List<PurchaseOrderItem> purchaseOrderItems = purchaseOrderItemDao.findByEnUUAndOrderCodeAndNumber(
								enUU, badOutItem.getOrderItem().getOrder().getCode(),
								badOutItem.getOrderItem().getNumber());
                        // 对应的采购单存在
						if (purchaseOrderItems.size() > 0) {
                            // 对应的采购单明细set进去
							badOutItem.setOrderItem(purchaseOrderItems.get(0));
							badOutItem.setOrderItemId(purchaseOrderItems.get(0).getId());
                            // 设置主记录
							badOutItem.setBadOut(badOut);
							badOutItem.setErpDate(new Date(System.currentTimeMillis()));
							badOutItems.add(badOutItem);
						} else {
							it.remove();
						}
					}
				}
			}
		}
		return badOutItems;
	}

	@Override
	public List<PurchaseAccept> convertNonPostingProdInOuts(List<PurchaseProdInOut> prodInOuts) {
		List<PurchaseAccept> accepts = new ArrayList<PurchaseAccept>();
		if (!CollectionUtils.isEmpty(prodInOuts)) {
			Long enUU = SystemSession.getUser().getEnterprise().getUu();
			for (PurchaseProdInOut prodInOut : prodInOuts) {
				List<PurchaseAccept> existAccepts = purchaseAcceptDao.findByEnUUAndCode(enUU,
						prodInOut.getPi_inoutno());
				if (existAccepts.size() > 0) {
					accepts.add(existAccepts.get(0));
				}
			}
		}
		return accepts;
	}

	@Override
	public List<PurchaseReturn> convertNonPostingReturns(List<PurchaseProdInOut> prodInOuts) {
		List<PurchaseReturn> returns = new ArrayList<PurchaseReturn>();
		if (!CollectionUtils.isEmpty(prodInOuts)) {
			Long enUU = SystemSession.getUser().getEnterprise().getUu();
			for (PurchaseProdInOut prodInOut : prodInOuts) {
				List<PurchaseReturn> existReturns = purchaseReturnDao.findByEnUUAndCode(enUU,
						prodInOut.getPi_inoutno());
				if (existReturns.size() > 0) {
					returns.add(existReturns.get(0));
				}
			}
		}
		return returns;
	}

	@Override
	public List<PurchaseBadIn> convertNonPostingBadIns(List<PurchaseProdInOut> prodInOuts) {
		List<PurchaseBadIn> badIns = new ArrayList<PurchaseBadIn>();
		if (!CollectionUtils.isEmpty(prodInOuts)) {
			Long enUU = SystemSession.getUser().getEnterprise().getUu();
			for (PurchaseProdInOut prodInOut : prodInOuts) {
				List<PurchaseBadIn> existBadIns = purchaseBadInDao.findByEnUUAndCode(enUU, prodInOut.getPi_inoutno());
				if (existBadIns.size() > 0) {
					badIns.add(existBadIns.get(0));
				}
			}
		}
		return badIns;
	}

	@Override
	public List<PurchaseBadOut> convertNonPostingBadOuts(List<PurchaseProdInOut> prodInOuts) {
		List<PurchaseBadOut> badOuts = new ArrayList<PurchaseBadOut>();
		if (!CollectionUtils.isEmpty(prodInOuts)) {
			Long enUU = SystemSession.getUser().getEnterprise().getUu();
			for (PurchaseProdInOut prodInOut : prodInOuts) {
				List<PurchaseBadOut> existBadOuts = purchaseBadOutDao.findByEnUUAndCode(enUU,
						prodInOut.getPi_inoutno());
				if (existBadOuts.size() > 0) {
					badOuts.add(existBadOuts.get(0));
				}
			}
		}
		return badOuts;
	}

	@Override
	public List<PurchaseAcceptItem> convertPirceForProdIn(List<ProdInOutRefreshPrice> prodInOuts) {
		List<PurchaseAcceptItem> acceptItems = new ArrayList<PurchaseAcceptItem>();
		List<OrderDetailPrice> detailPriceList = new ArrayList<>();
		if (!CollectionUtils.isEmpty(prodInOuts)) {
			for (ProdInOutRefreshPrice prod : prodInOuts) {
				PurchaseAcceptItem acceptItem = purchaseAcceptItemDao.findByEnUUAndCodeAndNumber(
						SystemSession.getUser().getEnterprise().getUu(), prod.getPbu_inoutno(), prod.getPbu_pdno());
				if (null != acceptItem) {
					acceptItem.setOrderPrice(prod.getPbu_orderprice());
					acceptItem.setTaxrate(prod.getPbu_taxrate());
					acceptItems.add(acceptItem);
					if (null != acceptItem.getOrderItemId()) {
                        detailPriceList.add(new OrderDetailPrice(acceptItem.getOrderItemId(), acceptItem.getOrderPrice(), acceptItem.getTaxrate()));
					}
				}
			}
		}
		// 更新对应的采购单信息
		if (!CollectionUtils.isEmpty(detailPriceList)) {
            purchaseService.refreshPrice(detailPriceList, OrderType.saleaccept.name());
        }
		return acceptItems;
	}

	/**
	 * 获取B2B对应的id
	 *
	 * @param prodInOuts ERP采购验收单
	 * @return
	 */
	@Override
	public List<PurchaseProdInOut> getAcceptB2bId(List<PurchaseProdInOut> prodInOuts) {
	    for (PurchaseProdInOut inOut : prodInOuts) {
            List<PurchaseAccept> existAccepts = purchaseAcceptDao.findByEnUUAndErpId(SystemSession.getUser().getEnterprise().getUu(),
                    inOut.getPi_id());
            if (!CollectionUtils.isEmpty(existAccepts)) {
                inOut.setPi_b2b_id(existAccepts.get(0).getId());
            }
        }
		return prodInOuts;
	}

    /**
     * 获取采购验退单对应的B2Bid
     *
     * @param prodInOuts ERP采购验退单
     * @return
     */
    @Override
    public List<PurchaseProdInOut> getReturnB2bId(List<PurchaseProdInOut> prodInOuts) {
        for (PurchaseProdInOut inOut : prodInOuts) {
            List<PurchaseReturn> existReturns = purchaseReturnDao.findByEnUUAndErpId(SystemSession.getUser().getEnterprise().getUu(),
                    inOut.getPi_id());
            if (!CollectionUtils.isEmpty(existReturns)) {
                inOut.setPi_b2b_id(existReturns.get(0).getId());
            }
        }
        return prodInOuts;
    }

    /**
     * 获取不良品出库单对应的B2Bid
     *
     * @param prodInOuts erp不良品出库单
     * @return
     */
    @Override
    public List<PurchaseProdInOut> getProdBadInB2bId(List<PurchaseProdInOut> prodInOuts) {
        for (PurchaseProdInOut inOut : prodInOuts) {
            List<PurchaseBadIn> existBadIns = purchaseBadInDao.findByEnUUAndErpId(SystemSession.getUser().getEnterprise().getUu(),
                    inOut.getPi_id());
            if (!CollectionUtils.isEmpty(existBadIns)) {
                inOut.setPi_b2b_id(existBadIns.get(0).getId());
            }
        }
        return prodInOuts;
    }

    /**
     * 获取不良品出库单对应的B2Bid
     *
     * @param prodInOuts erp不良品出库单
     * @return
     */
    @Override
    public List<PurchaseProdInOut> getProdBadOutB2bId(List<PurchaseProdInOut> prodInOuts) {
        for (PurchaseProdInOut inOut : prodInOuts) {
            List<PurchaseBadOut> existBadOuts = purchaseBadOutDao.findByEnUUAndErpId(SystemSession.getUser().getEnterprise().getUu(),
                    inOut.getPi_id());
            if (!CollectionUtils.isEmpty(existBadOuts)) {
                inOut.setPi_b2b_id(existBadOuts.get(0).getId());
            }
        }
        return prodInOuts;
    }

}
