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

import com.uas.platform.b2b.dao.*;
import com.uas.platform.b2b.erp.model.B2BCustomer;
import com.uas.platform.b2b.erp.model.B2BVendor;
import com.uas.platform.b2b.erp.model.VendorRecommend;
import com.uas.platform.b2b.model.*;
import com.uas.platform.b2b.service.VendorService;
import com.uas.platform.b2b.support.SystemSession;
import com.uas.platform.core.model.Constant;
import com.uas.platform.core.model.PageInfo;
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 VendorsServiceImpl implements VendorService {

	@Autowired
	private VendorDao vendorDao;

	@Autowired
	private VendorContactDao vendorContactDao;

	@Autowired
	private ProductDao productDao;

	@Autowired
	private CommonDao commonDao;

	@Autowired
	private com.uas.platform.b2b.erp.service.VendorService vendorService;

    /**
     * 应用来源
     */
    private final String APPID = "uas";

	@Override
	public Vendor addVendor(Vendor vendor) {
		vendor.setMyEnUU(SystemSession.getUser().getEnterprise().getUu());
		vendor.setMyEnterprise(SystemSession.getUser().getEnterprise());
		vendor.setCustswitch(Constant.YES);
		vendor.setVendswitch(Constant.YES);
		Vendor vendor1 = vendorDao.save(vendor);
		vendorService.addPartnerShipRecord(vendor1, APPID); // 添加合作伙伴关系
		return vendor1;
	}

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

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

	@Override
	public List<Vendor> findMyCustomersUsingErp() {
		// UAS系统或优企云服
		return vendorDao.findCustByVendUUAndCustPlatform(SystemSession.getUser().getEnterprise().getUu(), Constant.YES, Constant.YES);
	}

	@Override
	public List<Vendor> findMyCustomerUsingErp(long custUU) {
		return vendorDao.findByCustAndVendAndCustPlatform(custUU, SystemSession.getUser().getEnterprise().getUu(), Constant.YES,
				Constant.YES);
	}

	@Override
	public Vendor findById(Long id) {
		return vendorDao.findOne(id);
	}

	@Override
	public VendorContact saveContact(VendorContact vendor) {
		VendorContact vendorContact = new VendorContact();
		if (vendor.getId() == null) {// 新增
			vendor.setDate(new Date());
			vendor.setMyenuu(SystemSession.getUser().getEnterprise().getUu());
			vendor.setUseruu(SystemSession.getUser().getUserUU());
			vendorContact = vendorContactDao.save(vendor);
		} else {// 编辑修改
			VendorContact ve = vendorContactDao.findOne(vendor.getId());
			ve.setDate(new Date());
			ve.setEmail(vendor.getEmail());
			ve.setMyenuu(vendor.getMyenuu());
			ve.setPhone(vendor.getPhone());
			ve.setPosition(vendor.getPosition());
			ve.setSex(vendor.getSex());
			ve.setTel(vendor.getTel());
			ve.setUseruu(SystemSession.getUser().getUserUU());
			ve.setVenduser(vendor.getVenduser());
			ve.setVenduu(vendor.getVenduu());
			vendorContact = vendorContactDao.save(ve);
		}
		return vendorContact;

	}

	@Override
	public ModelMap getVendorsAndCustomers(Long enUU) {
		ModelMap map = new ModelMap();
		List<B2BVendor> B2BVendors = new ArrayList<>();
		List<Vendor> vendors = vendorDao.findByMyEnUU(enUU);
		for (Vendor vendor : vendors) {
			B2BVendor b2BVendor = new B2BVendor(vendor);
			B2BVendors.add(b2BVendor);
		}
		List<B2BCustomer> B2BCustomers = new ArrayList<>();
		List<Vendor> customers = vendorDao.findByVendEnUU(enUU);
		for (Vendor customer : customers) {
			B2BCustomer b2BCustomer = new B2BCustomer(customer);
			B2BCustomers.add(b2BCustomer);
		}
		map.put("B2BVendors", B2BVendors);
		map.put("B2BCustomers", B2BCustomers);
		return map;
	}

	/**
	 * 获取当前企业推荐供应商
	 *
	 * @param enUU 当前企业UU
	 * @param productMatchCondition 物料模糊匹配条件
	 * @param enterpriseMatchCondition 企业搜索匹配条件
	 * @param page 页面
	 * @param size 每页条数
	 * @return
	 */
	@Override
	public com.uas.sso.support.Page<VendorRecommend> getVendorRecommend(Long enUU, String productMatchCondition, String enterpriseMatchCondition, int page, int size) {
		long start = System.currentTimeMillis();
        if (null == enUU) {
            // 设置不存在的企业
            enUU = 100411660L;
        }
        if (StringUtils.isEmpty(productMatchCondition) || productMatchCondition.contains("1=1")) {
			productMatchCondition = " 1=1 ";
		} else {
        	productMatchCondition = productMatchCondition + " and pr_issale = 1";
		}
		if (StringUtils.isEmpty(enterpriseMatchCondition)) {
			enterpriseMatchCondition = " 1=1 ";
		}
		// 查询所有的企业信息
		StringBuffer enterpriseSql = new StringBuffer();
		enterpriseSql.append("select en.en_uu, en.en_name, en.en_shortname, en.en_address, en.en_tel, en.en_email, en.en_corporation, en.en_businesscode, en.en_profession, en.en_tags, en.en_contactman, en.en_contacttel from sec$enterprises en right join (" +
				" select en_uu, count(1) as counts from sec$enterprises left join products on en_uu = pr_enuu where ").append(productMatchCondition).append(" and en_uu <> ")
				.append(enUU).append(" and en_name not like '%测试%' and lower(en_name) not like '%test%' and ").append(enterpriseMatchCondition).append(" group by en_uu order by count(1) desc" +
				" ) a on en.en_uu = a.en_uu order by en.en_weight desc, counts desc");
		// rownum 控制
		String rownumSql = ") s limit " + (page - 1) * size + "," + size;
		// 查找非供应商的卖当前商品的企业UU
		StringBuffer vendorRecommendUusSql = new StringBuffer();
		// and instr(Pr_Title,'测试')<1 and instr(lower(Pr_Title),'test')<1
		vendorRecommendUusSql.append("select s.*,( select group_concat(pr_title , (case when pr_brand is not null then concat('(', pr_brand, ')') else ' ' end)) from v$products where pr_enuu=en_uu and ")
				.append(productMatchCondition).append(" and pr_issale = 1 and pr_b2bdisabled <> 1 limit 0,5 " +
				" ) productInfo, (select 1 from purc$vendors where ve_vendenuu = en_uu and ve_myenuu = ").append(enUU)
				.append(") isVendor from (").append(enterpriseSql).append(rownumSql);
		// 因为需求更改为所有有销售产品的企业都会被返回，所以total直接取除本企业外其他有销售产品的企业数即可，之前的匹配企业数不再返回
		StringBuffer totalSql = new StringBuffer().append(" select count(1) from (select en_uu from sec$enterprises left join " +
				" products on en_uu = pr_enuu where en_name not like '%测试%' and lower(en_name) not like '%test%' and en_uu <> ")
				.append(enUU).append(" and ").append(productMatchCondition).append(" and ").append(enterpriseMatchCondition).append(" group by en_uu) a");
		Integer total = commonDao.queryForObject(totalSql.toString(), Integer.class);
		List<VendorRecommend> vendorRecommends = commonDao.query(vendorRecommendUusSql.toString(), VendorRecommend.class);
		System.out.println("查找完企业UU" + (System.currentTimeMillis() - start));
		return new com.uas.sso.support.Page<VendorRecommend>(page, size, vendorRecommends, total);
	}


	/**
	 * 获取推荐企业物料列表（匹配到的排前面）
	 *
	 * @param page           页数
	 * @param size           每页条数
	 * @param vendUU         推荐供应商企业UU
	 * @param productMatchCondition 列表的物料匹配搜索条件 -- 需求变更中，此条件已弃用
	 * @param whereCondition where条件（product的筛选条件拼接）
	 * @return
	 */
	@Override
	public com.uas.sso.support.Page<Product> getProductsByVendorRecommend(int page, int size, Long enUU, Long vendUU, String productMatchCondition, String whereCondition) {
		// 如果enUU不为空按之前的处理，为空另外处理
		if (StringUtils.isEmpty(whereCondition)) {
			whereCondition = " 1 = 1 ";
		}
		List<Product> products = new ArrayList<>();
		if (null != enUU) {
			System.out.println("进入方法：" + System.currentTimeMillis());
			long start = System.currentTimeMillis();
			// UAS企业UU
			StringBuffer cmpCodesSql = new StringBuffer();
			cmpCodesSql.append("select 1 from v$products where pr_cmpcode = p1.pr_cmpcode and pr_enuu = ")
					.append(enUU).append(" and ifnull(pr_issale,0) <> 1 and pr_ispurchase = 1 and pr_b2bdisabled <> 1 and Pr_Title not like '%测试%' and Pr_Title not like '%test%' and Pr_code not like '%测试%' and Pr_code not like '%test%' ");
			// 查找匹配在售物料的语句
			StringBuffer productsMatchSql = new StringBuffer();
			productsMatchSql.append("select pr_id from (select pr_id from v$products p1 where exists (").append(cmpCodesSql).append(") and p1.pr_enuu = ").append(vendUU)
					.append(" and p1.pr_issale = 1 and p1.pr_b2bdisabled <> 1 and p1.Pr_Title not like '%测试%' and p1.Pr_Title not like '%test%' and p1.Pr_code not like '%测试%' and p1.Pr_code not like '%test%' and ")
					.append(whereCondition).append(" order by pr_standard desc, pr_id desc) a");
			// 查找不匹配但是在售物料的语句  union all 方便排序
			StringBuffer notMatchProductsSql = new StringBuffer();
			notMatchProductsSql.append("select pr_id from (select pr_id from v$products p1 where not exists (").append(cmpCodesSql).append(") and p1.pr_enuu = ").append(vendUU)
					.append(" and p1.pr_issale = 1 and p1.pr_b2bdisabled <> 1 and p1.Pr_Title not like '%测试%' and p1.Pr_Title not like '%test%' and p1.Pr_code not like '%测试%' and p1.Pr_code not like '%test%' and ")
					.append(whereCondition).append(" order by pr_standard desc, pr_id desc)");
			// 物料id
			StringBuffer idSql = new StringBuffer();
			// rownum 控制
			String rownumSql = " ) t limit " + (page - 1) * size + "," + size;
			idSql.append("select pr_id from (").append(productsMatchSql).append(" union all ").append(notMatchProductsSql)
					.append(" b").append(rownumSql);
			List<Long> matchedIds = commonDao.queryForList(productsMatchSql.toString(), Long.class);
			List<Long> ids = commonDao.queryForList(idSql.toString(), Long.class);
			for (Long id : ids) {
				Product product = productDao.findOne(id);
				if (matchedIds.contains(id)) {
					StringBuffer matchCodeSql = new StringBuffer();
					matchCodeSql.append("select wm_concat(pr_code) from v$products where pr_b2bdisabled <> 1 and pr_enuu = ")
							.append(enUU).append(" and pr_cmpcode = '").append(product.getCmpCode()).append("'").append(" and rownum <= 5");
					String matchCodes = commonDao.queryForObject(matchCodeSql.toString(), String.class);
					product.setIfMatched(matchCodes);
				}
				products.add(product);
			}
			System.out.println("返回数据：" + (System.currentTimeMillis() - start));
		} else {
			String prodSql = "select a.* from (select t.*,rownum as r1 from (select pr_id id, pr_code code, pr_title title, pr_spec spec, pr_cmpcode cmpCode, pr_unit unit, pr_kind kind, "
					+ "pr_minpack minPack, pr_minOrder minOrder, pr_brand brand, pr_standard standard, pr_issale isSale, pr_ispurchase isPurchase from v$products where pr_enuu = "
					+ vendUU + " and pr_issale = 1 and pr_b2bdisabled <> 1 and Pr_Title not like '%测试%' and lower(Pr_Title) not like '%test%' and Pr_code not like '%测试%' and lower(Pr_code) not like '%test%' and "
					+ whereCondition + " order by pr_issale desc, pr_standard desc, pr_id desc) t where rownum <= " + page * size + ") a where r1 > " + (page - 1) * size;
			System.out.println("无UU：" + prodSql);
			products = commonDao.query(prodSql, Product.class);

		}
		String countSql = "select count(1) from v$products where pr_enuu = " + vendUU
				+ " and pr_issale = 1 and pr_b2bdisabled <> 1 and Pr_Title not like '%测试%' and lower(Pr_Title) not like '%test%' and Pr_code not like '%测试%' and lower(Pr_code) not like '%test%' and "
				+ whereCondition;
		Integer count = commonDao.queryForObject(countSql, Integer.class);
		return new com.uas.sso.support.Page<>(page, size, products, count);
	}

	/**
	 * 根据条件获取物料型号和品牌值对
	 *
	 * @param field 需要的字段名
	 * @param condition 物料模糊匹配条件
	 * @return 物料型号和品牌值对List
	 */
	@Override
	public List<Product> getProductAssociate(String field, String condition) {
		if (StringUtils.isEmpty(condition) || StringUtils.isEmpty(field)) {
			return null;
		}
		String value = field.replace("pr_", "");
		String productSql = "select " + field + " as " + value +" from (" +
				" select " + field + " from v$products where " + condition + " group by " + field +
				") where rownum <= 10";
		return commonDao.query(productSql, Product.class);
	}

}
