package com.yd.rmi.cache;

import com.yd.dal.entity.customer.AclInsurerBranch;
import com.yd.dal.entity.meta.*;
import com.yd.dal.service.customer.AclInsurerBranchDALService;
import com.yd.dal.service.meta.*;
import com.yd.dal.service.practitioner.PractitionerHiringDALService;
import com.yd.rmi.ali.ossinterf.service.AliOssInterfService;
import com.yd.util.CommonUtil;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author xxy
 */
@Service("systemConfigService")
@org.springframework.core.annotation.Order(1)
public class SystemConfigService implements CommandLineRunner{
	private static Cache systemConfigCache = SystemCacheManager.getCache("systemConfigCache");
	@Autowired
	private MdCodeDALService mdCodeService;
	@Autowired
	private AliOssInterfService aliOssInterfService;
	@Autowired
	private MdPractitionerHiringApproveStepsDALService mdPractitionerHiringApproveStepsDalService;
	@Autowired
	private MdMkCampaignDALService mdMkCampaignDALService;
	@Autowired
	private MdIncometaxRateDALService mdIncometaxRateDALService;
	@Autowired
	private MdDropOptionsDALService mdDropOptionsDALService;
	@Autowired
	private AclInsurerBranchDALService aclInsurerBranchDALService;
	@Autowired
	private PractitionerHiringDALService practitionerHiringDalService;

	/**
	 * 保存cache
	 * @param cacheKey
	 * @param cacheValue
	 */
	public void setCache(String cacheKey,String cacheValue){
		if(!"".equals(cacheKey) && cacheKey != null){
			//先清除原有的数据
			Element element = systemConfigCache.get(cacheKey);
			if(element != null && element.getObjectValue() != null){
				systemConfigCache.remove(cacheKey);
			}
			//保存新的数据
			element = new Element(cacheKey,cacheValue);
			systemConfigCache.put(element);
		}
	}

	/**
	 * 获取cache
	 * @param cacheKey
	 */
	public String getCache(String cacheKey){
		if(!"".equals(cacheKey) && cacheKey != null){
			//先清除原有的数据
			Element element = systemConfigCache.get(cacheKey);
			if(element != null && element.getObjectValue() != null){
				return (String)element.getObjectValue();
			}
		}
		return null;
	}

	/**
	 * 删除cache
	 * @param cacheKey
	 */
	public void deleteCache(String cacheKey){
		if(!"".equals(cacheKey) && cacheKey != null){
			//先清除原有的数据
			Element element = systemConfigCache.get(cacheKey);
			if(element != null && element.getObjectValue() != null){
				systemConfigCache.remove(cacheKey);
			}
		}
	}

	/**
	 * 根据配置类型去获取相应配置
	 * @param configType
	 * @return
	 */
	public String getSingleConfigValue(String configType){
		return getSingleConfigValue(configType,null);
	}
	
	/**
	 * 根据配置类型去获取相应配置
	 * @param configType 配置类型
	 * @param codeNameEn 配置具体类型的名称
	 * @return
	 */
	public String getSingleConfigValue(String configType,String codeNameEn){
		String configValue = null;
		Element element = systemConfigCache.get(configType+codeNameEn);
		if(element != null && element.getObjectValue() != null){
			configValue = (String)element.getObjectValue();
		}else{
			MdCode mdCode = new MdCode();
			mdCode.setCodeType(configType);
			mdCode.setIsActive(1);
			if(!CommonUtil.isNullOrBlank(codeNameEn)){
				mdCode.setCodeNameEn(codeNameEn);
			}
//			System.out.println("------------------------------查询"+configType+"并放入缓存");
			List<MdCode> mdCodeList = mdCodeService.findByMdCode(mdCode);
			if(mdCodeList != null && mdCodeList.size()>0){
				mdCode = mdCodeList.get(0);
				configValue = mdCode.getCodeCode();
				element = new Element(configType+codeNameEn,configValue);
				systemConfigCache.put(element);
			}
		}
		return configValue;
	}

	/**
	 * 慎用！以免出现和keyValueMap中的key冲突，导致转换异常。
	 * 建议使用getKeyValueMap来替代此方法
	 * @param configType
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<String> getListConfigValue(String configType){
		List<String> configValues = null;
		Element element = systemConfigCache.get(configType);
		if(element != null && element.getObjectValue() != null){
			configValues = (List<String>)element.getObjectValue();
		}else{
			MdCode mdCode = new MdCode();
			mdCode.setCodeType(configType);
			mdCode.setIsActive(1);
			List<MdCode> mdCodeList = mdCodeService.findByMdCode(mdCode);
			if(mdCodeList != null && mdCodeList.size()>0){
				configValues = new ArrayList<String>();
				for(MdCode md : mdCodeList){
					configValues.add(md.getCodeCode());	
				}
				element = new Element(configType,configValues);
				systemConfigCache.put(element);
			}
		}
		return configValues;
	}

	public void clearConfig(String configType){
//    	getKeyValueMap(configType);
    	
		Element element = systemConfigCache.get(configType);
//		System.out.println("------------------------------清除"+configType+"缓存前获取的值"+element);
		if(element != null && element.getObjectValue() != null){
			systemConfigCache.remove(configType);
			System.out.println("------------------------------清除"+configType+"缓存");
		}
		element = systemConfigCache.get(configType);
//		System.out.println("------------------------------清除"+configType+"缓存后获取的值"+element);
    }

	public boolean mobileInfoProduct(Long productId,String configType){
		if(productId != null){
			MdCode mdCode = new MdCode();
			mdCode.setCodeType(configType);
			mdCode.setIsActive(1);
			List<MdCode> mdCodeList = mdCodeService.findByMdCode(mdCode);
			if(!mdCodeList.isEmpty()){
				mdCode = mdCodeList.get(0);
				String productIdStr = mdCode.getCodeCode();
				String[] productIdS = productIdStr.split(",");
				List<String> productIdList = Arrays.asList(productIdS);
				if(!productIdList.isEmpty() && productIdList.contains(productId.toString())){
					return true;
				}
			}
		}
		return false;
	}

	public Map<String, String> getKeyValueMap(String configType) {
		Map<String, String> keyValueMap = null;

		Element element = systemConfigCache.get(configType);
		if (element != null && element.getObjectValue() != null) {
			keyValueMap = (Map<String, String>) element.getObjectValue();
		} else {
			MdCode mdCode = new MdCode();
			mdCode.setCodeType(configType);
			mdCode.setIsActive(1);
			List<MdCode> mdCodeList = mdCodeService.findByMdCode(mdCode);
			if (mdCodeList != null && mdCodeList.size() > 0) {
				keyValueMap = new HashMap<String, String>();
				for (MdCode md : mdCodeList) {
					keyValueMap.put(md.getCodeCode(), md.getCodeName());
				}
			}
			element = new Element(configType, keyValueMap);
			systemConfigCache.put(element);
		}
		return keyValueMap;
	}

	public Map<String,String> geMdCodeIdMap(String configType){
		Map<String,String> keyValueMap = null;
		Element element = systemConfigCache.get(configType);
		if(element != null && element.getObjectValue() != null){
			keyValueMap = (Map<String,String>)element.getObjectValue();
		}else{
			MdCode mdCode = new MdCode();
			mdCode.setCodeType(configType);
			mdCode.setIsActive(1);
			List<MdCode> mdCodeList = mdCodeService.findByMdCode(mdCode);
			if(mdCodeList != null && mdCodeList.size()>0){
				keyValueMap = new HashMap<String,String>();
				for(MdCode md : mdCodeList){
					keyValueMap.put(md.getId().toString(), md.getCodeName());
				}
			}
			element = new Element(configType,keyValueMap);
			systemConfigCache.put(element);
		}
		return keyValueMap;
	}

	/**
	 * 试算因子对应保费
	 * @param elements 试算因子
	 * @param result 对应价格,无planId拼装数据
	 * @return
	 */
	public String getElementsForPrice(String elements,String result){
		//当传入price时,存入缓存      当没有传price时,做查询
		if (!CommonUtil.isNullOrBlank(result)) {
			Element element = new Element(elements,result);
			systemConfigCache.put(element);
		}else{
			Element element = systemConfigCache.get(elements);
			if(element != null && element.getObjectValue() != null){
				result = (String)element.getObjectValue();
			}
		}
		return result;
	}

	@Override
	public void run(String... arg0) throws Exception {
//		SystemConstants.ALI_OSS_ENDPOINT = getSingleConfigValue("ALI_OSS_ENDPOINT");
//		SystemConstants.ALI_OSS_ACCESS_KEY_ID = getSingleConfigValue("ALI_OSS_ACCESS_KEY_ID");
//		SystemConstants.ALI_OSS_ACCESS_KEY_SECRET = getSingleConfigValue("ALI_OSS_ACCESS_KEY_SECRET");
//		SystemConstants.ALI_OSS_BUCKET_NAME = getSingleConfigValue("ALI_OSS_BUCKET_NAME");
		SystemConstants.COMMON_CONNECTION_TIMEOUT = Integer.parseInt(getSingleConfigValue("COMMON_CONNECTION_TIMEOUT"));
		SystemConstants.COMMON_SO_TIMEOUT = Integer.parseInt(getSingleConfigValue("COMMON_SO_TIMEOUT"));
		aliOssInterfService.initAttribute();
	}


    public Long getMdMkCampaignId(String campaignCode) {
		Long configValue = null;
		Element element = systemConfigCache.get("campaignCode:"+campaignCode);
		if(element != null && element.getObjectValue() != null){
			configValue = (Long)element.getObjectValue();
		}else{
			MdMkCampaign mkCampaign = mdMkCampaignDALService.findByCampaignCode(campaignCode);
			configValue = Optional.ofNullable(mkCampaign).map(c -> c.getId()).orElse(null);
			element = new Element("campaignCode:"+campaignCode,configValue);
			systemConfigCache.put(element);
		}
		return configValue;
    }

	@SuppressWarnings("unchecked")
    public List<MdIncometaxRate> findIncometax(){
		List<MdIncometaxRate> incometaxRates = new ArrayList<>();
		Element element = systemConfigCache.get("MdIncometaxRate");
		if(element != null && element.getObjectValue() != null){
			incometaxRates = (List<MdIncometaxRate>)element.getObjectValue();
		}else{
			incometaxRates  = mdIncometaxRateDALService.findAll();
			element = new Element("MdIncometaxRate",incometaxRates);
			systemConfigCache.put(element);
		}
		return incometaxRates;
	}

	public MdDropOptions getDropOption(String masterCode, String optionCode) {
		if (CommonUtil.isNullOrBlank(masterCode) || CommonUtil.isNullOrBlank(optionCode)) {
			return null;
		}
		MdDropOptions mdDropOption;
		Element element = systemConfigCache.get(masterCode + optionCode);
		if (element != null && element.getObjectValue() != null) {
			mdDropOption = (MdDropOptions) element.getObjectValue();
		} else {
			mdDropOption = mdDropOptionsDALService.selectByMasterCodeAndOptionsCode(masterCode, optionCode);
			element = new Element(masterCode + optionCode, mdDropOption);
			systemConfigCache.put(element);
		}
		return mdDropOption;
	}

	public MdDropOptions getDropOptionInfo(String elementKey, String dropOptionId, String masterCode) {
		if (CommonUtil.isNullOrBlank(elementKey) || CommonUtil.isNullOrBlank(masterCode) || CommonUtil.isNullOrBlank(dropOptionId)) {
			return null;
		}
		ConcurrentHashMap<String, MdDropOptions> mdDropOptionsMap;
		Element element = systemConfigCache.get(elementKey);
		if (element != null && element.getObjectValue() != null) {
			mdDropOptionsMap = (ConcurrentHashMap<String, MdDropOptions>) element.getObjectValue();
		} else {
			List<MdDropOptions> mdDropOptionsList = mdDropOptionsDALService.findByDropMasterCode(masterCode);
			mdDropOptionsMap = new ConcurrentHashMap<>();
			mdDropOptionsList.forEach(i -> mdDropOptionsMap.put(i.getId() + "", i));
			element = new Element(elementKey, mdDropOptionsMap);
			systemConfigCache.put(element);
		}
		return mdDropOptionsMap.get(dropOptionId);
	}

	@SuppressWarnings("unchecked")
    public List<MdPractitionerHiringApproveSteps> findHiringApproveStepsByPractitionerLevel(String practitionerLevelCode) {
		List<MdPractitionerHiringApproveSteps> hiringApproveSteps = new ArrayList<>();
		Element element = systemConfigCache.get("HiringApproveSteps"+practitionerLevelCode);
		if(element != null && element.getObjectValue() != null){
			hiringApproveSteps = (List<MdPractitionerHiringApproveSteps>)element.getObjectValue();
		}else{
			hiringApproveSteps  = mdPractitionerHiringApproveStepsDalService.findByPractitionerLevel(practitionerLevelCode);
			element = new Element("HiringApproveSteps"+practitionerLevelCode,hiringApproveSteps);
			systemConfigCache.put(element);
		}
		return hiringApproveSteps;
    }

	@SuppressWarnings("unchecked")
	public List<String> findHiringApproveMobileNo(List<MdPractitionerHiringApproveSteps> hiringApproveSteps ,String practitionerLevelCode) {
		List<String> hiringApproveMobileNos = new ArrayList<>();
		Element element = systemConfigCache.get("HiringApproveMobileNo"+practitionerLevelCode);
		if(element != null && element.getObjectValue() != null){
			hiringApproveMobileNos = (List<String>)element.getObjectValue();
		}else{
			for (MdPractitionerHiringApproveSteps hiringApproveStep : hiringApproveSteps){
				String appointedApprovePractitioners = hiringApproveStep.getAppointedApprovePractitioners();
				if (!CommonUtil.isNullOrBlank(appointedApprovePractitioners)){
					hiringApproveMobileNos.addAll(Arrays.asList(appointedApprovePractitioners.split(",")));
				}
			}
			//去重
			hiringApproveMobileNos = hiringApproveMobileNos.stream().distinct().collect(Collectors.toList());
			element = new Element("HiringApproveMobileNo"+practitionerLevelCode,hiringApproveMobileNos);
			systemConfigCache.put(element);
		}
		return hiringApproveMobileNos;
	}

	@SuppressWarnings("unchecked")
	public List<MdPractitionerHiringApproveSteps> findHiringApproveStepsAll() {
		List<MdPractitionerHiringApproveSteps> hiringApproveSteps = new ArrayList<>();
		Element element = systemConfigCache.get("HiringApproveStepsAll");
		if(element != null && element.getObjectValue() != null){
			hiringApproveSteps = (List<MdPractitionerHiringApproveSteps>)element.getObjectValue();
		}else{
			hiringApproveSteps  = mdPractitionerHiringApproveStepsDalService.findAll();
			element = new Element("HiringApproveStepsAll",hiringApproveSteps);
			systemConfigCache.put(element);
		}
		return hiringApproveSteps;
	}

    public Map<Long, AclInsurerBranch> getAclInsurerBranchMap() {
        Map<Long, AclInsurerBranch> map = null;
        Element element = systemConfigCache.get("aclInsurerBranchMap");
        if (element != null && element.getObjectValue() != null) {
            map = (Map<Long, AclInsurerBranch>) element.getObjectValue();
        } else {
            List<AclInsurerBranch> list = aclInsurerBranchDALService.findAll();
            if (list != null && list.size() > 0) {
                map = new HashMap<Long, AclInsurerBranch>();
                for (AclInsurerBranch item : list) {
                    map.put(item.getId(), item);
                }
            }
            element = new Element("aclInsurerBranchMap", map);
            systemConfigCache.put(element);
        }
        return map;
    }

}
