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

import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.erp.model.ProdInOutRefreshPrice;
import com.uas.platform.b2b.erp.support.ErpBufferedLogger;
import com.uas.platform.b2b.model.Product;
import com.uas.platform.b2b.model.PurchaseApBill;
import com.uas.platform.b2b.model.PurchaseApBillItem;
import com.uas.platform.b2b.model.SearchFilter;
import com.uas.platform.b2b.search.SearchService;
import com.uas.platform.b2b.service.PurchaseApBillService;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.core.logging.BufferedLoggerManager;
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.Date;
import java.util.List;

@Service
public class PurchaseApBillServiceImpl implements PurchaseApBillService {

	@Autowired
	private PurchaseApBillDao purchaseApBillDao;

	@Autowired
	private PurchaseApBillItemDao purchaseApBillItemDao;

	@Autowired
	private SearchService searchService;

	@Autowired
	private CommonDao commonDao;

	@Autowired
	private ProductDao productDao;

	private final static ErpBufferedLogger logger = BufferedLoggerManager.getLogger(ErpBufferedLogger.class);

	@Override
	public void save(List<PurchaseApBillItem> apBillItems) {
		purchaseApBillItemDao.save(apBillItems);
	}

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

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

	@Override
	public Page<PurchaseApBill> findAllByPageInfo(final PageInfo pageInfo, final String keyword, final Long fromDate,
			final Long endDate, final SearchFilter filter) {
		return purchaseApBillDao.findAll(new Specification<PurchaseApBill>() {

			@Override
            public Predicate toPredicate(Root<PurchaseApBill> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
				if (filter != null) {
					if (!CollectionUtils.isEmpty(filter.getDistribute())) {

					}
					pageInfo.expression(PredicateUtils.in("vendUU", filter.getDistribute(), false));
				}
				if (StringUtils.hasText(keyword)) {
					List<Object> lists = new ArrayList<>();
					PageParams pageParams = new PageParams();
					ModelMap map = new ModelMap();
					map.put("pad_venduu", SystemSession.getUser().getEnterprise().getUu());
					pageParams.setFilters(map);
					for (PurchaseApBill list : searchService.searchPurchaseApBillIds(keyword, pageParams)
							.getContent()) {
						lists.add(list.getId());
					}
					pageInfo.expression(PredicateUtils.in("id", lists, false));
				}
				if (fromDate != null) {
                    pageInfo.expression(PredicateUtils.in("id", purchaseApBillDao.findByFromDate(
                            SystemSession.getUser().getEnterprise().getUu(), new Date(fromDate)), false));
                }
				if (endDate != null) {
                    pageInfo.expression(PredicateUtils.in("id", purchaseApBillDao
                            .findByEndDate(SystemSession.getUser().getEnterprise().getUu(), new Date(endDate)), false));
                }
				query.where(pageInfo.getPredicates(root, query, builder));
				return null;
			}
		}, pageInfo);
	}

	@Override
	public PurchaseApBill findById(Long id) {
		return purchaseApBillDao.findOne(id);
	}

	@Override
	public void nonPosting(List<PurchaseApBill> apBills) {
		if (!CollectionUtils.isEmpty(apBills)) {
			for (PurchaseApBill apBill : apBills) {
				if (apBill.getSendStatus() == Status.DOWNLOADED.value()) {
					// 已传输到供应商ERP，修改单据反过账状态
					apBill.setNonPosting(Constant.YES);
					purchaseApBillDao.save(apBill);
				} else {
					// 未传输到供应商ERP，直接删除平台上的单据
					purchaseApBillDao.delete(apBill);
				}
			}
		}

	}

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

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

	@Override
	public void refreshPrice(List<ProdInOutRefreshPrice> prodInOuts) {
		Long enuu = SystemSession.getUser().getEnterprise().getUu();
		if(!CollectionUtils.isEmpty(prodInOuts)) {
			for(ProdInOutRefreshPrice prod : prodInOuts) {
				// 只更新一条数据，这里只能用物料编号去判断，采购单序号等无法判断
				List<Product> prods = productDao.findByEnUUAndCode(enuu, prod.getPd_prodcode());
				if(!CollectionUtils.isEmpty(prods)) {
					// 更新明细单价、税率
					String sql = " update purc$apbillitem i,purc$apbill a set i.papi_price = " + prod.getPbu_orderprice() + ", i.papi_apamount = i.papi_thisvoqty * "
							+ prod.getPbu_orderprice() + ", i.papi_amount = i.papi_qty * " + prod.getPbu_orderprice();
					if (null != prod.getPbu_taxrate()) {
						sql = sql + ", i.papi_taxrate = " + prod.getPbu_taxrate() + ", i.papi_taxamount = ROUND(i.papi_qty * "
								+ prod.getPbu_orderprice() + "/(1 +" + prod.getPbu_taxrate()/100 + ") * " + prod.getPbu_taxrate()/100 + ", 2)";
					} else {
						sql = sql + ", i.papi_taxamount = ROUND(i.papi_qty * " + prod.getPbu_orderprice() + "/(1 + (IFNULL(i.papi_taxrate, 0)/100)) * (IFNULL(i.papi_taxrate, 0)/100), 2)";
					}
					sql = sql +" where i.papi_papid = a.pab_id and i.papi_pdinoutno = 'ET18040001' and a.pad_enuu = 10041166 and i.papi_product = 23839348";
					commonDao.getJdbcTemplate().update(sql);
					logger.log("批量更新价格", "更新'" + prod.getPbu_inoutno() + "'发票明细价格", 1);
					// 更新主表的税金合计
					purchaseApBillDao.refreshAmountAndTaxSum(SystemSession.getUser().getEnterprise().getUu(), prod.getPbu_inoutno());
				}
			}
		}
	}

}
