package com.rrtx.services.common.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.min.util.CommonUtil;
import com.rrtx.services.common.exception.BusinessException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 合并SQL查询后List工具类
 * @author dudm@minpay.cc
 *
 */
public class ListUtil {
	public static void mergeList(
			IPage<?> page,
			List<?> list2,
			String[] strings,
			String[] strings2,
			String[] strings3
	) throws BusinessException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
		List<?> list = page.getRecords();
		List resList = mergeList(list, list2, strings, strings2, strings3);
		page.setRecords(resList);
	}

	/**
	 * 将查询出的两个List按指定参数合并
	 * list  		主表数据(分页)
	 * list2		副表数据(不分页)
	 * strings		主表的关联字段(数量及顺序必须与副表字段相同 例如：[id,name])
	 * strings2		副表的关联字段(数量及顺序必须与主表字段相同 例如：[uId,uName])
	 * strings3		要合并的副表中字段[sex, age]
	 * @throws BusinessException
	 *
	 */
	public static List mergeList(
			List<?> list,
			List<?> list2,
			String[] strings,
			String[] strings2,
			String[] strings3
	) throws BusinessException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
		List<Map> listAll = new ArrayList<Map>();
		//关联字段数不可为空
		if(strings.length == 0){
			throw new BusinessException("关联字段名称不可为空！");
		}
		//关联字段数量必须相同
		if(strings.length != strings2.length){
			throw new BusinessException("两个List的关联字段数量不同！");
		}
		for (int i = 0; i < list.size(); i++) {
			Map map = new HashMap();
			//主表
			Object t = list.get(i);
			for (int j = 0; j < list2.size(); j++) {
				//副表
				Object t2 = list2.get(j);
				for (int k = 0; k < strings.length; k++) {
					String stringsKey = null;

					// list1泛型是map
					if (t instanceof Map) {
						Map tMap = (Map) t;
						stringsKey = String.valueOf(tMap.get(strings[k]));
						// list1泛型是实体类
					} else {
						Class tClass = t.getClass();
						Method mapGet = tClass.getDeclaredMethod("get"+toUpper(strings[k]));
						stringsKey = (String)mapGet.invoke(t);
					}
					String strings2Key = null;
					// list2泛型是map
					if (t2 instanceof Map) {
						Map t2Map = (Map) t2;
						strings2Key = t2Map.get(strings2[k]).toString();
					} else {
						Class t2Class = t2.getClass();
						Method mapGet = t2Class.getDeclaredMethod("get"+toUpper(strings2[k]));
						strings2Key = String.valueOf(mapGet.invoke(t2));
					}

					//关联字段名称不能为空
					/*if(CommonUtil.isEmpty(stringsKey)||CommonUtil.isEmpty(strings2Key)){
						System.out.println("为空："+strings[k]);
						System.out.println("或为空：" + strings2[k]);
						throw new BusinessException("关联字段名称不可为空！");
					}*/
					//通过关联字段的值判断是否有关联 没有关联不作处理
					if(stringsKey == null || strings2Key == null || !stringsKey.equals(strings2Key)){
						break;
					}
					//如果所有关联字段的值都相等那么合并map
					if((k+1) == strings.length){
						//根据要合并的字段合并map
						for (int k2 = 0; k2 < strings3.length; k2++) {
							String strings3Val = null;
							// list2泛型是map
							if (t2 instanceof Map) {
								Map t2Map = (Map) t2;
								strings3Val = t2Map.get(strings3[k2]).toString();
							} else {
								Class t2Class = t2.getClass();
								Method mapGet = t2Class.getDeclaredMethod("get"+toUpper(strings3[k2]));
								strings3Val = (String)mapGet.invoke(t2);
							}

							if(CommonUtil.isEmpty(strings3Val)){
								//如果不存在则赋空
								map.put(strings3[k2], "");
							}else{
								//存在则赋值
								map.put(strings3[k2], strings3Val);
							}
						}
					}
				}
			}

			// list1泛型是map
			if (t instanceof Map) {
				Map tempMap = new HashMap();
				Map tMap = (Map) t;
				// 重复属性 + I
				for (Object keyObj : map.keySet()) {
					if (tMap.containsKey(keyObj)) {
						tempMap.put(keyObj + "I", map.get(keyObj));
						continue;
					}
					tempMap.put(keyObj, map.get(keyObj));
				}
				map = tempMap;
				map.putAll(tMap);
				// list1泛型是实体类
			} else {
				Class tClass =  t.getClass();
				Method[] getMethods = tClass.getDeclaredMethods();
				for (Method method : getMethods) {
					if (method.getName().startsWith("get")) {
						String value = String.valueOf(method.invoke(t));
						String key = toLower(method.getName().replace("get",""));

						// 重复属性 + I
						if (map.containsKey(key)) {
							map.put(key + "I", map.get(key));
							continue;
						}
						map.put(key, value);
					}
				}
			}
			listAll.add(map);
		}
		return listAll;
	}

	/**
	 * 将查询出的两个List合并
	 * list  		主表数据(分页)
	 * list2		副表数据(不分页)
	 * strings		主表的关联字段(数量及顺序必须与副表字段相同 例如：[id,name])
	 * strings2		副表的关联字段(数量及顺序必须与主表字段相同 例如：[uId,uName])
	 * @throws BusinessException
	 *
	 */
	public static List<Map<String, String>> mergeListAll(
			List<Map<String, String>> list,
			List<Map<String, String>> list2,
			String[] strings,
			String[] strings2
	) throws BusinessException{
		//最终返回的组合
		List<Map<String, String>> listAll = list;
		//关联字段数不可为空
		if(strings.length == 0){
			throw new BusinessException("关联字段名称不可为空！");
		}
		//关联字段数量必须相同
		if(strings.length != strings2.length){
			throw new BusinessException("两个List的关联字段数量不同！");
		}
		for (int i = 0; i < listAll.size(); i++) {
			//主表
			Map<String, String> map = list.get(i);
			for (int j = 0; j < list2.size(); j++) {
				//副表
				Map<String, String> map2 = list2.get(j);
				for (int k = 0; k < strings.length; k++) {
					//关联字段名称不能为空
					if(CommonUtil.isEmpty(map.get(strings[k]))||CommonUtil.isEmpty(map2.get(strings2[k]))){
						throw new BusinessException("关联字段名称不可为空！");
					}
					//通过关联字段的值判断是否有关联 没有关联不作处理
					if(!map.get(strings[k]).equals(map2.get(strings2[k]))){
						break;
					}
					//如果所有关联字段的值都相等那么合并map
					if((k+1) == strings.length){
						map.putAll(map2);
					}
				}
			}
		}
		return listAll;
	}

	public static String toUpper(String str) {
		return str.substring(0,1).toUpperCase()+str.substring(1);
	}
	public static String toLower(String str) {
		return str.substring(0,1).toLowerCase()+str.substring(1);
	}

	public static void main(String[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
		/*List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		Map<String, String> map = new HashMap<>();
		map.put("id","1");
		list.add(map);

		List list2 = new ArrayList();
		Map<String, String> map2 = new HashMap<>();
		map2.put("personId","1");
		map2.put("name","张三");
		list2.add(map2);

		String[] str1 = {"id"};
		String[] str2 = {"personId"};
		String[] str3 = {"name"};
		List resList = mergeList(list, list2, str1, str2, str3);*/

		/*List<PubOrderInf> orderList = new ArrayList<PubOrderInf>();
		PubOrderInf order = new PubOrderInf();
		order.setPoiCreateUser("1");
		order.setPoiDesc("描述");
		orderList.add(order);

		List<PubPersonInf> personList = new ArrayList<PubPersonInf>();
		PubPersonInf personInf = new PubPersonInf();
		personInf.setPpiId("1");
		personInf.setPpiName("张三");
		personList.add(personInf);

		String[] str1 = {"poiCreateUser"};
		String[] str2 = {"ppiId"};
		String[] str3 = {"ppiName"};
		List resList = mergeList(orderList, personList, str1, str2, str3);*/

		//test(new PubPersonInf());
	}
}
	
