package com.prolog.rdc.tms.app.util;

import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.mapper.BaseMapper;
import com.prolog.rdc.tms.app.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.app.constant.StatusConstant;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * 
 *
 * 公共方法
 *
 * @className :PublicMethods
 * @author :fanzw
 * @creationTime :2021/12/22
 * @description :
 * @modifier :fanzw
 * @modifyTime :2021/12/22
 * @reviseRemarks:
 *
 * @version :1.0.0
 *
 */
public class PublicMethods {
	/**
	 * 参照数据翻译
	 *
	 * @param list
	 * @param character
	 * @return
	 */
	public static String change(List<Map<String, Object>> list, String character) {
		if (list == null || list.size() == 0 || character == null || character.equals("")) {
			return character;
		}

		String massage = null;
		for (Map<String, Object> map : list) {
			if ((map.get("value")).equals(character)) {
				massage = map.get("text").toString();
				break;
			}
		}

		return massage;
	}

	/**
	 * 参照数据反向翻译
	 *
	 * @param list
	 * @param character
	 * @return
	 */
	public static String reverseChange(List<Map<String, Object>> list, String character) {
		if (list == null || list.size() == 0 || character == null || character.equals("")) {
			return character;
		}

		String massage = null;
		for (Map<String, Object> map : list) {
			if ((map.get("text")).equals(character)) {
				massage = map.get("value").toString();
				break;
			}
		}

		return massage;
	}

	/**
	 * 数据字典转换赋值
	 * 
	 * @param obj                 对象
	 * @param maindataTmsResource resource服务
	 * @param dataDictionary      数据自字典
	 * @param fieldName           指定的字段
	 * @param originalValue       原始值
	 */
	public static void referenceDataProcessing(Object obj, MaindataFeign maindataTmsResource, String dataDictionary, String fieldName, String originalValue) {
		if (ToolKits.isEmpty(originalValue)) {
			return;
		}

		// 获取数据字典
		RestMessage<List<Map<String, Object>>> restMessage = maindataTmsResource.getDropDownById(dataDictionary, null, null, null);
		if (restMessage.isSuccess()) {
			// 数据字典详情
			List<Map<String, Object>> list = restMessage.getData();

			try {
				// 获取该类的成员变量
				Field displayName = obj.getClass().getDeclaredField(fieldName);
				// 取消语言访问检查
				displayName.setAccessible(true);

				// 数据字典处理
				if (FileUtils.StringType(originalValue)) {
					// 数据字典code处理
					Assert.notNull(PublicMethods.change(list, originalValue), "数据字典【" + dataDictionary + "】未配置【" + originalValue + "】属性");
					// 给变量赋值
					displayName.set(obj, Integer.valueOf(originalValue));
				} else {
					// 数据字典name处理
					Assert.notNull(PublicMethods.reverseChange(list, originalValue), "数据字典【" + dataDictionary + "】未配置【" + originalValue + "】属性");
					// 给变量赋值
					displayName.set(obj, Integer.valueOf(PublicMethods.reverseChange(list, originalValue)));
				}
			} catch (Exception e) {
				e.printStackTrace();

				throw new ParameterException("数据字典【" + dataDictionary + "】转换失败：" + e.getMessage());
			}
		} else {
			throw new ParameterException("数据字典【" + dataDictionary + "】获取失败：" + restMessage.getMessage());
		}
	}

	/**
	 * 判断指定信息是否存在
	 *
	 * @param clazz
	 * @param paramName1
	 * @param paramValue1
	 * @param paramName2
	 * @param paramValue2
	 * @param paramName3
	 * @param paramValue3
	 * @param mapper
	 * @param message
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void isThereAnyinformation(Class<?> clazz, String paramName1, String paramValue1, String paramName2, String paramValue2, String paramName3, Object paramValue3, BaseMapper mapper, String message) {
		Criteria criteria = Criteria.forClass(clazz);
		Restriction r1 = Restrictions.eq(paramName1, paramValue1);
		Restriction r2 = Restrictions.eq(paramName2, paramValue2);
		Restriction r3 = Restrictions.eq(paramName3, paramValue3);
		criteria.setRestriction(Restrictions.and(r1, r2, r3));
		List<T> list = mapper.findByCriteria(criteria);
		if (ToolKits.isNotEmpty(list)) {
			throw new ParameterException(message);
		}
	}

	/**
	 * 判断指定信息是否存在
	 *
	 * @param clazz
	 * @param paramName1
	 * @param paramValue1
	 * @param paramName2
	 * @param paramValue2
	 * @param mapper
	 * @param message
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void isThereAnyinformation(Class<?> clazz, String paramName1, String paramValue1, String paramName2, String paramValue2, BaseMapper mapper, String message) {
		Criteria criteria = Criteria.forClass(clazz);
		Restriction r1 = Restrictions.eq(paramName1, paramValue1);
		Restriction r2 = Restrictions.eq(paramName2, paramValue2);
		criteria.setRestriction(Restrictions.and(r1, r2));
		List<T> list = mapper.findByCriteria(criteria);
		if (ToolKits.isNotEmpty(list)) {
			throw new ParameterException(message);
		}
	}

	/**
	 * 根据map查询记录数
	 *
	 * @param mapper
	 * @param map
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static long findCountByMap(BaseMapper mapper, Map map, Class<?> clazz) {
		return mapper.findCountByMap(map, clazz);
	}

	/**
	 * 更具map判断是否存在
	 *
	 * @param mapper
	 * @param map
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void doesItExistByMap(BaseMapper mapper, Map map, Class<?> clazz, String message) {
		List<T> list = mapper.findByMap(map, clazz);
		if (ToolKits.isNotEmpty(list)) {
			throw new ParameterException(message);
		}
	}

	/**
	 * 格式转换
	 *
	 * @param str
	 * @return
	 */
	public static Integer FormatConversion(String str) {
		if (!StatusConstant.WHETHER_STRING_YES.equals(str) && !StatusConstant.WHETHER_STRING_NO.equals(str)) {
			throw new RuntimeException("格式不正确[是/否]");
		}
		return StatusConstant.WHETHER_STRING_YES.equals(str) ? 1 : 0;
	}

	/**
	 * 根据map更新自定字段
	 *
	 * @param field
	 * @param value
	 * @param map
	 * @param mapper
	 * @param clazz
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void updateMapByCriteria(String field, Long value, Map map, BaseMapper mapper, Class<?> clazz) {
		Criteria criteria = Criteria.forClass(clazz);
		Restriction r1 = Restrictions.eq(field, value);
		criteria.setRestriction(r1);
		mapper.updateMapByCriteria(map, criteria);
	}

	/**
	 * 标记类型值匹配
	 *
	 * @param matching
	 * @param compareValue
	 * @param compareValue2
	 * @return
	 */
	public static boolean compare(Integer matching, String compareValue, String compareValue2) {
		boolean results = false;
		switch (matching) {
		case DataDictionaryConstant.SIGNCONFIG_MATCHING_LIKE:
			results = compareValue2.contains(compareValue);
			break;
		case DataDictionaryConstant.SIGNCONFIG_MATCHING_NOT_LIKE:
			results = !compareValue2.contains(compareValue);
			break;
		case DataDictionaryConstant.SIGNCONFIG_MATCHING_NOT_NULL:
			results = ToolKits.isNotEmpty(compareValue2);
			break;
		case DataDictionaryConstant.SIGNCONFIG_MATCHING_NULL:
			results = ToolKits.isEmpty(compareValue2);
			break;
		case DataDictionaryConstant.SIGNCONFIG_MATCHING_EQ:
			results = compareValue.equals(compareValue2);
			break;
		case DataDictionaryConstant.SIGNCONFIG_MATCHING_NOT_EQ:
			results = !compareValue.equals(compareValue2);
			break;
		}
		return results;
	}

	/**
	 * 获取的异常信息，包括空指针异常处理
	 * @param e
	 * @return
	 */
	public static String getExceptionMessage(Exception e) {
		String str = "";
		if(e == null) {
			return str;
		}
		if(e instanceof NullPointerException) {
			str = getStackTraceMessage(e);
		}else {
			str = e.getMessage();
		}
		return str;
	}

	/**
	 * 获取statckTrace的异常信息
	 * @param e
	 * @return
	 */
	public static String getStackTraceMessage(Exception e) {
		if(e == null) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		StackTraceElement[] stackArray = e.getStackTrace();
		for (int i = 0; i < stackArray.length; i++) {
			StackTraceElement element = stackArray[i];
			sb.append(element.toString() + "\n");
		}
		return e.toString() + "\n" + sb.toString();
	}
}
