package com.ruoyi.system.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;

@Component
@SuppressWarnings("unchecked")
public class TrafficRedisHashUtil {
    private static final String TRAFFIC_DATA_HASH_KEY = "eps:traffic:hash";

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 使用Hash结构存储，每个taskId对应一个列表（支持泛型）
     */
    public <T> void saveListToHash(String taskId, List<T> dataList) {
        if (dataList == null) {
            return;
        }

        String hashKey = generateHashKey(taskId);
        redisTemplate.opsForHash().put(TRAFFIC_DATA_HASH_KEY, hashKey, dataList);

        // 可选：设置过期时间
//        redisTemplate.expire(TRAFFIC_DATA_HASH_KEY, 1, TimeUnit.HOURS);
    }

    /**
     * 从Hash获取数据（支持泛型）
     */
    public <T> List<T> getListFromHash(String taskId, Class<T> clazz) {
        String hashKey = generateHashKey(taskId);
        Object result = redisTemplate.opsForHash().get(TRAFFIC_DATA_HASH_KEY, hashKey);

        if (result instanceof List) {
            return (List<T>) result;
        }
        return new ArrayList<>();
    }

    /**
     * 从Hash获取数据（不指定类型，返回原始List）
     */
    public List<?> getListFromHash(String taskId) {
        String hashKey = generateHashKey(taskId);
        Object result = redisTemplate.opsForHash().get(TRAFFIC_DATA_HASH_KEY, hashKey);

        if (result instanceof List) {
            return (List<?>) result;
        }
        return null;
    }

    /**
     * 更新Hash中的特定项（通过createTime匹配）
     */
    public <T> void updateItemInHash(String taskId, T updatedItem, String createTime) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList != null) {
            for (int i = 0; i < dataList.size(); i++) {
                T item = dataList.get(i);
                String itemCreateTime = getCreateTimeFromObject(item);
                if (itemCreateTime != null && itemCreateTime.equals(createTime)) {
                    dataList.set(i, updatedItem);
                    break;
                }
            }
            saveListToHash(taskId, dataList);
        }
    }

    /**
     * 更新Hash中的特定项（使用自定义匹配器）
     */
    public <T> void updateItemInHash(String taskId, T updatedItem, Predicate<T> matcher) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList != null) {
            for (int i = 0; i < dataList.size(); i++) {
                if (matcher.test(dataList.get(i))) {
                    dataList.set(i, updatedItem);
                    break;
                }
            }
            saveListToHash(taskId, dataList);
        }
    }

    /**
     * 添加新数据项到指定taskId的列表
     */
    public <T> void addItemToHash(String taskId, T newItem) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList == null) {
            dataList = new ArrayList<>();
        }
        dataList.add(newItem);
        saveListToHash(taskId, dataList);
    }

    /**
     * 从指定taskId的列表中删除数据项（通过createTime匹配）
     */
    public <T> void deleteItemFromHash(String taskId, Object createTime) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList != null) {
            dataList.removeIf(item -> {
                Object itemCreateTime = getCreateTimeFromObject(item);
                return itemCreateTime != null && itemCreateTime.equals(createTime);
            });
            saveListToHash(taskId, dataList);
        }
    }

    /**
     * 从指定taskId的列表中删除数据项（使用自定义匹配器）
     */
    public <T> void deleteItemFromHash(String taskId, Predicate<T> matcher) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList != null) {
            dataList.removeIf(matcher);
            saveListToHash(taskId, dataList);
        }
    }

    /**
     * 根据createTime范围删除数据项
     */
    public <T> void deleteItemsByCreateTimeRange(String taskId, Object startTime, Object endTime) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList != null) {
            dataList.removeIf(item -> {
                Object itemCreateTime = getCreateTimeFromObject(item);
                if (itemCreateTime == null) return false;

                // 假设createTime是可比较的类型（如Date、Long、LocalDateTime等）
                if (itemCreateTime instanceof Comparable) {
                    Comparable<Object> time = (Comparable<Object>) itemCreateTime;
                    return time.compareTo(startTime) >= 0 && time.compareTo(endTime) <= 0;
                }
                return false;
            });
            saveListToHash(taskId, dataList);
        }
    }

    /**
     * 根据createTime查找数据项
     */
    public <T> T findItemByCreateTime(String taskId, Object createTime) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList != null) {
            for (T item : dataList) {
                Object itemCreateTime = getCreateTimeFromObject(item);
                if (itemCreateTime != null && itemCreateTime.equals(createTime)) {
                    return item;
                }
            }
        }
        return null;
    }

    /**
     * 根据createTime范围查找数据项
     */
    public <T> List<T> findItemsByCreateTimeRange(String taskId, Object startTime, Object endTime) {
        List<T> dataList = (List<T>) getListFromHash(taskId);
        List<T> result = new ArrayList<>();

        if (dataList != null) {
            for (T item : dataList) {
                Object itemCreateTime = getCreateTimeFromObject(item);
                if (itemCreateTime != null && itemCreateTime instanceof Comparable) {
                    Comparable<Object> time = (Comparable<Object>) itemCreateTime;
                    if (time.compareTo(startTime) >= 0 && time.compareTo(endTime) <= 0) {
                        result.add(item);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 获取最早的createTime数据项
     */
    public <T> T getEarliestItem(String taskId) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList == null || dataList.isEmpty()) {
            return null;
        }

        T earliestItem = dataList.get(0);
        Object earliestTime = getCreateTimeFromObject(earliestItem);

        for (int i = 1; i < dataList.size(); i++) {
            T currentItem = dataList.get(i);
            Object currentTime = getCreateTimeFromObject(currentItem);

            if (currentTime instanceof Comparable && earliestTime instanceof Comparable) {
                Comparable<Object> currentComparable = (Comparable<Object>) currentTime;
                Comparable<Object> earliestComparable = (Comparable<Object>) earliestTime;

                if (currentComparable.compareTo(earliestComparable) < 0) {
                    earliestItem = currentItem;
                    earliestTime = currentTime;
                }
            }
        }
        return earliestItem;
    }

    /**
     * 获取最晚的createTime数据项
     */
    public <T> T getLatestItem(String taskId) {
        List<T> dataList = (List<T>) getListFromHash(taskId);

        if (dataList == null || dataList.isEmpty()) {
            return null;
        }

        T latestItem = dataList.get(0);
        Object latestTime = getCreateTimeFromObject(latestItem);

        for (int i = 1; i < dataList.size(); i++) {
            T currentItem = dataList.get(i);
            Object currentTime = getCreateTimeFromObject(currentItem);

            if (currentTime instanceof Comparable && latestTime instanceof Comparable) {
                Comparable<Object> currentComparable = (Comparable<Object>) currentTime;
                Comparable<Object> latestComparable = (Comparable<Object>) latestTime;

                if (currentComparable.compareTo(latestComparable) > 0) {
                    latestItem = currentItem;
                    latestTime = currentTime;
                }
            }
        }
        return latestItem;
    }

    /**
     * 删除整个taskId对应的缓存
     */
    public void deleteTaskData(String taskId) {
        String hashKey = generateHashKey(taskId);
        redisTemplate.opsForHash().delete(TRAFFIC_DATA_HASH_KEY, hashKey);
    }

    /**
     * 检查taskId是否存在缓存
     */
    public boolean hasTaskData(String taskId) {
        String hashKey = generateHashKey(taskId);
        return redisTemplate.opsForHash().hasKey(TRAFFIC_DATA_HASH_KEY, hashKey);
    }

    /**
     * 获取所有已缓存的taskId列表
     */
    public Set<Object> getAllCachedTaskIds() {
        return redisTemplate.opsForHash().keys(TRAFFIC_DATA_HASH_KEY);
    }

    /**
     * 设置整个Hash的过期时间
     */
    public void setExpire(long timeout, TimeUnit unit) {
        redisTemplate.expire(TRAFFIC_DATA_HASH_KEY, timeout, unit);
    }

    /**
     * 获取Hash中所有数据的总数
     */
    public long getTotalSize() {
        return redisTemplate.opsForHash().size(TRAFFIC_DATA_HASH_KEY);
    }

    /**
     * 从对象中提取createTime字段值（支持继承链查找），并转换为字符串格式
     */
    public <T> String getCreateTimeFromObject(T item) {
        if (item == null) {
            return null;
        }

        System.out.println("开始查找createTime字段，对象类型: " + item.getClass().getName());

        // 在类的继承链中查找createTime字段
        Class<?> clazz = item.getClass();
        while (clazz != null && clazz != Object.class) {
            try {
                System.out.println("在当前类中查找: " + clazz.getName());
                java.lang.reflect.Field createTimeField = clazz.getDeclaredField("createTime");
                createTimeField.setAccessible(true);
                Object value = createTimeField.get(item);

                if (value != null) {
                    System.out.println("成功在 " + clazz.getName() + " 中找到createTime字段，值: " + value + ", 类型: " + value.getClass().getName());

                    // 将Date类型转换为字符串
                    return convertDateToString(value);
                }
                return null;

            } catch (NoSuchFieldException e) {
                // 当前类没有该字段，继续在父类中查找
                System.out.println(clazz.getName() + " 中没有createTime字段，继续查找父类");
                clazz = clazz.getSuperclass();
            } catch (Exception e) {
                System.out.println("获取字段值时发生异常: " + e.getMessage());
                return null;
            }
        }

        System.out.println("在整个继承链中都未找到createTime字段");
        return null;
    }

    /**
     * 将Date对象转换为 yyyy-MM-dd HH:mm:ss 格式的字符串
     */
    private String convertDateToString(Object dateObj) {
        if (dateObj == null) {
            return null;
        }

        try {
            // 如果是java.util.Date类型
            if (dateObj instanceof java.util.Date) {
                java.util.Date date = (java.util.Date) dateObj;
                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(date);
            }
            // 如果是java.sql.Date类型
            else if (dateObj instanceof java.sql.Date) {
                java.sql.Date sqlDate = (java.sql.Date) dateObj;
                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(new java.util.Date(sqlDate.getTime()));
            }
            // 如果是java.sql.Timestamp类型
            else if (dateObj instanceof java.sql.Timestamp) {
                java.sql.Timestamp timestamp = (java.sql.Timestamp) dateObj;
                java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return sdf.format(new java.util.Date(timestamp.getTime()));
            }
            // 如果是LocalDateTime类型（Java 8+）
            else if (dateObj instanceof java.time.LocalDateTime) {
                java.time.LocalDateTime localDateTime = (java.time.LocalDateTime) dateObj;
                return localDateTime.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
            // 如果是LocalDate类型（Java 8+）
            else if (dateObj instanceof java.time.LocalDate) {
                java.time.LocalDate localDate = (java.time.LocalDate) dateObj;
                return localDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00";
            }
            // 如果是字符串类型，直接返回
            else if (dateObj instanceof String) {
                return (String) dateObj;
            }
            // 其他类型，尝试转换为字符串
            else {
                return dateObj.toString();
            }
        } catch (Exception e) {
            System.out.println("日期转换异常: " + e.getMessage());
            return dateObj.toString(); // 转换失败时返回原始字符串
        }
    }

    private String generateHashKey(String taskId) {
        return "task:" + taskId;
    }
}