package com.corewing.app.handler;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.corewing.app.common.enums.CommonDeleteFlagEnum;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectionException;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;

/**
 * MyBatis-Plus 自动填充处理器
 * 兼容 Date 和 LocalDateTime 两种时间类型的自动填充
 */
@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {

    /** 删除标志 */
    private static final String DELETE_FLAG = "deleteFlag";

    /** 创建人 */
    private static final String CREATE_USER = "createUser";

    /** 创建时间 */
    private static final String CREATE_TIME = "createTime";

    /** 更新人 */
    private static final String UPDATE_USER = "updateUser";

    /** 更新时间 */
    private static final String UPDATE_TIME = "updateTime";

    @Override
    public void insertFill(MetaObject metaObject) {
        try {
            //为空则设置deleteFlag
            Object deleteFlag = metaObject.getValue(DELETE_FLAG);
            if (ObjectUtil.isNull(deleteFlag)) {
                setFieldValByName(DELETE_FLAG, EnumUtil.toString(CommonDeleteFlagEnum.NOT_DELETE), metaObject);
            }
        } catch (ReflectionException ignored) { }

        try {
            //为空则设置createUser
            Object createUser = metaObject.getValue(CREATE_USER);
            if (ObjectUtil.isNull(createUser)) {
                setFieldValByName(CREATE_USER, this.getUserId(), metaObject);
            }
        } catch (ReflectionException ignored) { }

        try {
            // 兼容 Date 和 LocalDateTime 类型的 createTime 填充
            fillTimeField(metaObject, CREATE_TIME);
        } catch (ReflectionException ignored) { }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        try {
            //设置updateUser
            setFieldValByName(UPDATE_USER, this.getUserId(), metaObject);
        } catch (ReflectionException ignored) {
        }

        try {
            // 兼容 Date 和 LocalDateTime 类型的 updateTime 填充
            fillTimeField(metaObject, UPDATE_TIME);
        } catch (ReflectionException ignored) {
        }
    }

    /**
     * 统一填充时间字段（自动识别 Date/LocalDateTime 类型）
     * @param metaObject 元对象
     * @param fieldName  时间字段名（createTime/updateTime）
     */
    private void fillTimeField(MetaObject metaObject, String fieldName) {
        // 先判断字段是否为空
        Object fieldValue = metaObject.getValue(fieldName);
        if (ObjectUtil.isNotNull(fieldValue)) {
            return; // 字段已有值，不填充
        }

        // 获取字段的类型，自动匹配填充值类型
        Class<?> fieldType = metaObject.getGetterType(fieldName);
        if (fieldType == LocalDateTime.class) {
            // 字段是 LocalDateTime 类型
            setFieldValByName(fieldName, LocalDateTime.now(), metaObject);
        } else if (fieldType == Date.class || fieldType == DateTime.class) {
            // 字段是 Date/hutool DateTime 类型
            setFieldValByName(fieldName, new Date(), metaObject);
        }
        // 其他类型不处理（避免填充错误）
    }

    /**
     * 获取用户id
     */
    private String getUserId() {
        try {
            String loginId = StpUtil.getLoginIdAsString();
            if (ObjectUtil.isNotEmpty(loginId)) {
                return loginId;
            } else {
                return "-1";
            }
        } catch (Exception e) {
            return "-1";
        }
    }
}