package com.emotion.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.emotion.util.SnowflakeIdGenerator;
import com.emotion.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * MyBatis-Plus 自动填充处理器
 * 自动填充公共字段：id, create_by, create_time, update_by, update_time
 * 支持雪花算法自动生成主键ID
 *
 * @author huazhongmin
 * @since 2025-07-23
 */
@Slf4j
@Component
public class EmotionMetaObjectHandler implements MetaObjectHandler {

    /**
     * 雪花算法ID生成器
     */
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    /**
     * 插入时自动填充
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        try {
            LocalDateTime now = LocalDateTime.now();
            String currentUserId = getCurrentUserId();

            // 填充主键ID（如果为空）
            fillPrimaryKey(metaObject);

            // 填充创建时间
            this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, now);

            // 填充更新时间
            this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, now);

            // 填充创建人ID
            if (currentUserId != null) {
                this.strictInsertFill(metaObject, "createBy", String.class, currentUserId);
            }

            // 填充更新人ID
            if (currentUserId != null) {
                this.strictInsertFill(metaObject, "updateBy", String.class, currentUserId);
            }

            // 填充逻辑删除字段默认值
            this.strictInsertFill(metaObject, "isDeleted", Integer.class, 0);

            log.debug("插入时自动填充完成: createTime={}, updateTime={}, createBy={}, updateBy={}",
                    now, now, currentUserId, currentUserId);

        } catch (Exception e) {
            // 自动填充失败不应该影响业务逻辑
            log.warn("插入时自动填充失败，但不影响业务逻辑: {}", e.getMessage());
        }
    }

    /**
     * 更新时自动填充
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        try {
            LocalDateTime now = LocalDateTime.now();
            String currentUserId = getCurrentUserId();

            // 填充更新时间
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, now);

            // 填充更新人ID
            if (currentUserId != null) {
                this.strictUpdateFill(metaObject, "updateBy", String.class, currentUserId);
            }

            log.debug("更新时自动填充完成: updateTime={}, updateBy={}", now, currentUserId);

        } catch (Exception e) {
            // 自动填充失败不应该影响业务逻辑
            log.warn("更新时自动填充失败，但不影响业务逻辑: {}", e.getMessage());
        }
    }

    /**
     * 填充主键ID
     * 如果主键ID为空，则使用雪花算法生成
     *
     * @param metaObject 元对象
     */
    private void fillPrimaryKey(MetaObject metaObject) {
        try {
            // 检查是否有id字段
            if (metaObject.hasSetter("id")) {
                Object idValue = metaObject.getValue("id");
                // 如果ID为空，则生成新的ID
                if (idValue == null || (idValue instanceof String && ((String) idValue).isEmpty())) {
                    String newId = snowflakeIdGenerator.nextIdAsString();
                    this.strictInsertFill(metaObject, "id", String.class, newId);
                    log.debug("自动生成主键ID: {}", newId);
                }
            }
        } catch (Exception e) {
            log.warn("主键ID自动填充失败，但不影响业务逻辑: {}", e.getMessage());
        }
    }

    /**
     * 获取当前用户ID
     * 优先级：
     * 1. 从ThreadLocal获取（如果有用户上下文）
     * 2. 从Spring Security获取（如果有认证信息）
     * 3. 返回系统默认值
     *
     * @return 当前用户ID，如果获取失败返回null
     */
    private String getCurrentUserId() {
        try {
            // 1. 尝试从ThreadLocal获取用户ID（如果有用户上下文工具类）
            String userIdFromContext = getUserIdFromContext();
            if (userIdFromContext != null) {
                return userIdFromContext;
            }

            // 2. 尝试从Spring Security获取用户ID
            String userIdFromSecurity = getUserIdFromSecurity();
            if (userIdFromSecurity != null) {
                return userIdFromSecurity;
            }

            // 3. 返回系统默认值（用于系统操作或未登录用户）
            return "system";

        } catch (Exception e) {
            log.debug("获取当前用户ID失败: {}", e.getMessage());
            return "system";
        }
    }

    /**
     * 从用户上下文获取用户ID
     * 这里可以集成自定义的用户上下文工具类
     * 
     * @return 用户ID或null
     */
    private String getUserIdFromContext() {
        try {
            // 从线程变量获取
            return UserContextHolder.getCurrentUserId();

        } catch (Exception e) {
            log.debug("从用户上下文获取用户ID失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从Spring Security获取用户ID
     * 
     * @return 用户ID或null
     */
    private String getUserIdFromSecurity() {
        try {
            // TODO: 集成Spring Security
            // Authentication authentication =
            // SecurityContextHolder.getContext().getAuthentication();
            // if (authentication != null && authentication.isAuthenticated()
            // && !"anonymousUser".equals(authentication.getPrincipal())) {
            // UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            // return userDetails.getUsername(); // 或者从UserDetails中获取用户ID
            // }
            return null;

        } catch (Exception e) {
            log.debug("从Spring Security获取用户ID失败: {}", e.getMessage());
            return null;
        }
    }
}
