package com.yeejoin.amos.boot.module.jg.biz.utils;

import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.yeejoin.amos.boot.biz.common.typeHandler.DictTypeHandler;
import com.yeejoin.amos.boot.biz.common.typeHandler.TypeHandler;
import com.yeejoin.amos.boot.module.jg.api.annotation.DictCode2DictName;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
public class DictUtil {

    /**
     * 配合注解@DictCode2DictName(code="",type="")使用
     * 将字段从dictCode转化为dictName
     * 日期格式化，使用@JsonFormat注解
     *
     * @param data 需要转化的数据
     */
    public static void dictCode2DictName(Object data) {
        if (data == null) {
            return;
        }

        // 处理 List 类型
        if (data instanceof List<?>) {
            List<?> list = (List<?>) data;
            for (Object item : list) {
                dictCode2DictName(item); // 递归处理每个元素
            }
        } else {
            // 处理单个对象
            Field[] fields = data.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);

                if (field.isAnnotationPresent(DictCode2DictName.class)) {
                    try {
                        DictCode2DictName annotation = field.getAnnotation(DictCode2DictName.class);
                        String code = Objects.toString(field.get(data));
                        String type = annotation.type();
                        String typeHandler = annotation.typeHandler();
                        String name = "";
                        if ("null".equals(code)) {
                            continue;
                        }

                        Object handler = SpringUtil.getBean(typeHandler);

                        if (handler instanceof DictTypeHandler) {
                            name = ((DictTypeHandler) handler).handle(type, code);
                        } else if (handler instanceof TypeHandler) {
                            name = Objects.toString(((TypeHandler) handler).handle(code));
                        } else {
                            log.warn("未识别的 handler 类型：{}", handler.getClass().getName());
                        }

                        field.set(data, name);
                    } catch (IllegalAccessException | IllegalArgumentException e) {
                        log.error("字段赋值失败: {}, 类型: {}", field.getName(), data.getClass().getName(), e);
                    }
                } else if (field.isAnnotationPresent(JsonFormat.class)) {
                    try {
                        Object value = field.get(data);
                        if (value == null) continue;

                        JsonFormat jsonFormat = field.getAnnotation(JsonFormat.class);
                        String pattern = jsonFormat.pattern();
                        if (pattern == null || pattern.isEmpty()) continue;

                        String formatted = null;

                        if (value instanceof Date) {
                            formatted = new SimpleDateFormat(pattern).format((Date) value);
                        } else if (value instanceof LocalDateTime) {
                            formatted = ((LocalDateTime) value).format(DateTimeFormatter.ofPattern(pattern));
                        } else if (value instanceof LocalDate) {
                            formatted = ((LocalDate) value).format(DateTimeFormatter.ofPattern(pattern));
                        } else if (value instanceof Long) { // 时间戳
                            Date date = new Date((Long) value);
                            formatted = new SimpleDateFormat(pattern).format(date);
                        } else if (value instanceof String) {
                            String str = (String) value;
                            LocalDateTime parsedDateTime = null;
                            str = str.trim().replaceAll("^[^\\d]+", "");
                            // 判断是否是长整型时间戳字符串
                            if (str.matches("^\\d{13,}$")) {
                                try {
                                    long timestamp = Long.parseLong(str);
                                    Date date = new Date(timestamp);
                                    formatted = new SimpleDateFormat(pattern).format(date);
                                } catch (Exception e) {
                                    throw e;
                                }
                            } else {
                                // 尝试常规格式解析
                                String[] parsePatterns = {
                                        "yyyy-MM-dd HH:mm:ss",
                                        "yyyy-MM-dd'T'HH:mm:ss",
                                        "yyyy-MM-dd"
                                };

                                for (String parsePattern : parsePatterns) {
                                    try {
                                        DateTimeFormatter parser = DateTimeFormatter.ofPattern(parsePattern);
                                        if (parsePattern.contains("HH")) {
                                            parsedDateTime = LocalDateTime.parse(str, parser);
                                        } else {
                                            parsedDateTime = LocalDate.parse(str, parser).atStartOfDay();
                                        }
                                        break;
                                    } catch (Exception ignore) {
                                    }
                                }

                                if (parsedDateTime != null) {
                                    formatted = parsedDateTime.format(DateTimeFormatter.ofPattern(pattern));
                                }
                            }
                        }
                        if (formatted != null) {
                            if (field.getType().equals(String.class)) {
                                field.set(data, formatted);
                            }
                        }
                    } catch (Exception e) {
                        log.error("日期字段: " + field.getName() + " 格式化失败: " + e.getMessage());
                    }
                }
            }
        }
    }
}
