package com.quantgroup.asset.distribution.service.asset.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.quantgroup.asset.distribution.service.feature.IFeatureService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Stopwatch;
import com.quantgroup.asset.distribution.constant.AssetAttributeConstants;
import com.quantgroup.asset.distribution.exception.QGException;
import com.quantgroup.asset.distribution.exception.QGExceptionType;
import com.quantgroup.asset.distribution.exception.QGPreconditions;
import com.quantgroup.asset.distribution.model.form.AssetForm;
import com.quantgroup.asset.distribution.service.asset.IAssetAttributeService;
import com.quantgroup.asset.distribution.service.httpclient.IHttpService;
import com.quantgroup.asset.distribution.service.jpa.entity.Asset;
import com.quantgroup.asset.distribution.service.jpa.entity.AssetAttributeExtend;
import com.quantgroup.asset.distribution.service.jpa.entity.AssetAttributeExtendConfig;
import com.quantgroup.asset.distribution.service.jpa.repository.IAssetAttributeExtendRepository;
import com.quantgroup.asset.distribution.service.jpa.repository.IAssetRepository;

import lombok.extern.slf4j.Slf4j;

/**
 * 资产扩展属性Service
 * 
 * @author liwenbin
 *
 */
@Slf4j
@Service
public class AssetAttributeServiceImpl implements IAssetAttributeService {
	
	@Autowired
	private IAssetRepository assetRepository;
	@Autowired
	private IAssetAttributeExtendRepository assetAttributeExtendRepository;
	@Autowired
	private IFeatureService featureService;


	/**
	 * 获取所有资产扩展属性value
	 */
	@Override
	public Map<String, Object> getAllAssetAttributeValue(List<AssetAttributeExtendConfig> assetAttributeExtendConfigList, AssetForm assetForm) {
		Stopwatch stopwatch = Stopwatch.createStarted();
		Map<String, Object> data = new HashMap<>();
		// 决策特征Key
		Set<String> decKeys = new HashSet<>();
		// 自有属性
		Set<String> propertyKeys = new HashSet<>();
		// 必填特征...慎用，会花钱的
		Set<String> necessaryKeys = new HashSet<>();
		decKeys.add(AssetAttributeConstants.USER_LOAN_TYPE);
		if (assetAttributeExtendConfigList != null && assetAttributeExtendConfigList.size() > 0) {
			for (AssetAttributeExtendConfig config : assetAttributeExtendConfigList) {
				if (config.getAssetAttributeType() == 1) {
					decKeys.add(config.getAssetAttributeCode()); 
				} else if (config.getAssetAttributeType() == 2) {
					// 自有属性，amount和term
					propertyKeys.add(config.getAssetAttributeCode());
				} else if (config.getAssetAttributeType() == 3) {
					// 决策必填特征
					necessaryKeys.add(config.getAssetAttributeCode());
				}

			}
		}
		// 请求决策特征
		Map<String, Object> decAttributeValue = getDecAttributeValue(decKeys, assetForm);
		data.putAll(decAttributeValue);
		// 必填特征, 慎用....
		Map<String, Object> necAttributeValue = getDecNecAttributeValue(necessaryKeys, assetForm);
		data.putAll(necAttributeValue);
		// 自有属性
		Map<String, Object> propertyValue = getPropertyAttributeValue(propertyKeys, assetForm);
		data.putAll(propertyValue);
		log.info("用户所有资产扩展属性获取完成, uuid : {}, assetNo : {}, bizNo : {}, bizType : {}, 耗时 : {}", assetForm.getUuid(), assetForm.getAssetNo(), assetForm.getBizNo(), assetForm.getBizType(), stopwatch.stop().elapsed(TimeUnit.MILLISECONDS));
		return data;
	}

	/**
	 * 获取必填特征
	 * @param necessaryKeys
	 * @param assetForm
	 * @return
	 */
	public Map<String, Object> getDecNecAttributeValue(Set<String> necessaryKeys, AssetForm assetForm) {
		return featureService.getFeatureData(necessaryKeys, assetForm, 1);
	}

	/**
	 * 获取所有决策特征属性值
	 * @param decKeys
	 * @param assetForm
	 * @return
	 */
	public Map<String, Object> getDecAttributeValue(Set<String> decKeys, AssetForm assetForm) {
		return featureService.getFeatureData(decKeys, assetForm, 0);
	}


	/**
	 * 获取自有属性值
	 * @param propertyKeys
	 * @param assetForm
	 * @return
	 */
	public Map<String, Object> getPropertyAttributeValue(Set<String> propertyKeys, AssetForm assetForm) {
		if (CollectionUtils.isEmpty(propertyKeys)) { return MapUtils.EMPTY_MAP; }
		JSONObject json = JSON.parseObject(JSON.toJSONString(assetForm));
		Map<String, Object> data = new HashMap<>();
		for (String propertyKey : propertyKeys) {
			String value = json.getString(propertyKey);
			if (StringUtils.isNotEmpty(value)) {
				data.put(propertyKey, value);
			}
		}
		return data;
	}

	@Transactional(rollbackFor=Exception.class)
	@Override
	public void saveAssetAttrubite(Asset asset, List<AssetAttributeExtendConfig> assetAttributeExtendConfigList,
			Map<String, Object> data) {
		// 用户类型特殊处理
		QGPreconditions.checkArgument(data.get(AssetAttributeConstants.USER_LOAN_TYPE) != null, QGExceptionType.ASSET_ATTRIBUTE_IS_EMPTY, AssetAttributeConstants.USER_LOAN_TYPE);
		asset.setUserLoanType((Integer)data.get(AssetAttributeConstants.USER_LOAN_TYPE));
		assetRepository.save(asset);
		
		if (assetAttributeExtendConfigList != null && assetAttributeExtendConfigList.size() > 0) {
			for (AssetAttributeExtendConfig config : assetAttributeExtendConfigList) {
				// 2019-9-11定位扩展属性允许为空
//				QGPreconditions.checkArgument(data.get(config.getAssetAttributeCode()) != null, QGExceptionType.ASSET_ATTRIBUTE_IS_EMPTY, config.getAssetAttributeCode());
				if (data.get(config.getAssetAttributeCode()) != null) {
					AssetAttributeExtend attributeExtend = new AssetAttributeExtend();
					attributeExtend.setAssetNo(asset.getAssetNo());
					attributeExtend.setAssetAttributeName(config.getAssetAttributeName());
					attributeExtend.setAssetAttributeCode(config.getAssetAttributeCode());
					attributeExtend.setAssetAttributeType(config.getAssetAttributeType());
					attributeExtend.setAssetAttributeValue(String.valueOf(data.get(config.getAssetAttributeCode())));
					attributeExtend.setEnable(true);
					assetAttributeExtendRepository.save(attributeExtend);
				}
			}
		}
	}
}
