package cn.gov.customs.wxjy.utils;

import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * List分割工具类
 * 用于将实体类中指定字段的逗号分隔值分割成多条记录
 */
public class ListSplitUtil {

	/**
	 * 根据指定字段的逗号分隔值分割列表
	 *
	 * @param originalList 原始列表
	 * @param fieldName    要分割的字段名
	 * @param <T>          实体类型
	 * @return 分割后的列表
	 */
	public static <T> List<T> splitByField(List<T> originalList, String fieldName) {
		if (originalList == null || originalList.isEmpty()) {
			return new ArrayList<>();
		}

		List<T> resultList = new ArrayList<>();

		for (T originalItem : originalList) {
			try {
				// 获取分割字段的值
				String fieldValue = getFieldValue(originalItem, fieldName);

				if (fieldValue == null || fieldValue.trim().isEmpty()) {
					// 如果字段值为空，直接添加原对象
					resultList.add(originalItem);
					continue;
				}

				// 按逗号分割，并去除空格
				List<String> splitValues = Arrays.stream(fieldValue.split(","))
					.map(String::trim)
					.filter(s -> !s.isEmpty())
					.collect(Collectors.toList());

				if (splitValues.isEmpty()) {
					// 如果分割后为空，直接添加原对象
					resultList.add(originalItem);
					continue;
				}

				// 为每个分割值创建新对象
				for (String splitValue : splitValues) {
					T newItem = copyObject(originalItem);
					setFieldValue(newItem, fieldName, splitValue);
					resultList.add(newItem);
				}

			} catch (Exception e) {
				// 如果处理过程中出现异常，添加原对象并继续处理其他项
				resultList.add(originalItem);
				System.err.println("处理对象时发生异常: " + e.getMessage());
			}
		}

		return resultList;
	}



	/**
	 * 获取字段值
	 */
	private static <T> String getFieldValue(T obj, String fieldName) throws Exception {
		Class<?> clazz = obj.getClass();
		Field field = getDeclaredField(clazz, fieldName);
		if (field == null) {
			throw new IllegalArgumentException("字段 '" + fieldName + "' 在类 " + clazz.getName() + " 中不存在");
		}

		field.setAccessible(true);
		Object value = field.get(obj);
		return value != null ? value.toString() : null;
	}

	/**
	 * 设置字段值
	 */
	private static <T> void setFieldValue(T obj, String fieldName, String value) throws Exception {
		Class<?> clazz = obj.getClass();
		Field field = getDeclaredField(clazz, fieldName);
		if (field == null) {
			throw new IllegalArgumentException("字段 '" + fieldName + "' 在类 " + clazz.getName() + " 中不存在");
		}

		field.setAccessible(true);

		// 根据字段类型设置值
		Class<?> fieldType = field.getType();
		if (fieldType == String.class) {
			field.set(obj, value);
		} else if (fieldType == Integer.class || fieldType == int.class) {
			field.set(obj, Integer.parseInt(value));
		} else if (fieldType == Long.class || fieldType == long.class) {
			field.set(obj, Long.parseLong(value));
		} else if (fieldType == Double.class || fieldType == double.class) {
			field.set(obj, Double.parseDouble(value));
		} else if (fieldType == Float.class || fieldType == float.class) {
			field.set(obj, Float.parseFloat(value));
		} else {
			// 其他类型直接设置为字符串
			field.set(obj, value);
		}
	}

	/**
	 * 复制对象（浅拷贝）
	 */
	private static <T> T copyObject(T original) throws Exception {
		Class<?> clazz = original.getClass();
		T copy = (T) clazz.newInstance();
		BeanUtils.copyProperties(original, copy);
//		Field[] fields = clazz.getDeclaredFields();
//		for (Field field : fields) {
//			field.setAccessible(true);
//			Object value = field.get(original);
//			field.set(copy, value);
//		}

		return copy;
	}

	/**
	 * 递归获取字段（包括父类字段）
	 */
	private static Field getDeclaredField(Class<?> clazz, String fieldName) {
		for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
			try {
				return superClass.getDeclaredField(fieldName);
			} catch (NoSuchFieldException e) {
				// 继续在父类中查找
			}
		}
		return null;
	}

	/**
	 * 批量分割多个字段（按顺序分割）
	 *
	 * @param originalList 原始列表
	 * @param fieldNames   要分割的字段名数组
	 * @param <T>          实体类型
	 * @return 分割后的列表
	 */
	public static <T> List<T> splitByFields(List<T> originalList, String... fieldNames) {
		if (fieldNames == null || fieldNames.length == 0) {
			return originalList;
		}

		List<T> result = originalList;
		for (String fieldName : fieldNames) {
			result = splitByField(result, fieldName);
		}
		return result;
	}
}
