package org.qinan.safetyeval.infrastructure.support;

import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * insert 前补齐 GBS 默认字段。
 * <p>
 * 作为 MyMetaObjectHandler 的防御性补充：当 MyBatis-Plus MetaObjectHandler 因框架冲突等原因
 * 未生效时，此工具类确保 GBS 标准字段在 insert 前显式填充。
 * 用户信息优先从 AuthUserContextAdapter（SSO）获取。
 * </p>
 */
public final class InsertFieldDefaults {

    private static final String DELETE_NOT_DELETED = "false";
    private static final String DEFAULT_ENV = "prod";

    private InsertFieldDefaults() {
    }

    public static void apply(Object dataObject) {
        if (dataObject == null) {
            return;
        }
        LocalDateTime now = LocalDateTime.now();

        // 常量默认值
        setIfNull(dataObject, "deleteEnum", DELETE_NOT_DELETED);
        setIfNull(dataObject, "env", DEFAULT_ENV);
        setIfNull(dataObject, "version", 0);

        // 时间字段
        setIfNull(dataObject, "createTime", now);
        setIfNull(dataObject, "updateTime", now);

        // 用户上下文字段：从 AuthUserContextAdapter 获取
        Long userId = AuthUserContextAdapter.getCurrentUserId();
        String userName = AuthUserContextAdapter.getCurrentUserName();
        Long tenantId = AuthUserContextAdapter.getCurrentTenantId();
        Long orgId = AuthUserContextAdapter.getCurrentOrgId();
        // 机构信息id
        Long orgInfoId = ThreadLocalUserInfoAdapter.get();


        if (userId != null) {
            setIfNull(dataObject, "createId", userId);
            setIfNull(dataObject, "updateId", userId);
        }
        if (userName != null) {
            setIfNull(dataObject, "createName", userName);
            setIfNull(dataObject, "updateName", userName);
        }
        if (tenantId != null) {
            setIfNull(dataObject, "tenantId", tenantId);
        }
        if (orgInfoId != null) {
            // 机构信息id
            setIfNull(dataObject, "orgId", orgInfoId);
        }
    }

    /**
     * insert 前补齐 GBS 默认字段，并允许指定额外的用户名（用于特定业务场景的 entity.operatorName 等）。
     */
    public static void applyWithUserName(Object dataObject, String overrideUserName) {
        apply(dataObject);
        if (overrideUserName != null) {
            setIfNull(dataObject, "createName", overrideUserName);
            setIfNull(dataObject, "updateName", overrideUserName);
        }
    }

    /**
     * update 前补齐 GBS 更新字段（updateTime、updateId、updateName）。
     * 防御性补充 MyMetaObjectHandler 未生效的场景。
     */
    public static void applyForUpdate(Object dataObject) {
        if (dataObject == null) {
            return;
        }
        LocalDateTime now = LocalDateTime.now();
        Long userId = AuthUserContextAdapter.getCurrentUserId();
        String userName = AuthUserContextAdapter.getCurrentUserName();
        // 机构信息id
        Long orgInfoId = ThreadLocalUserInfoAdapter.get();

        setIfNull(dataObject, "updateTime", now);
        if (userId != null) {
            setIfNull(dataObject, "updateId", userId);
        }
        if (userName != null) {
            setIfNull(dataObject, "updateName", userName);
        }
        if (orgInfoId != null) {
            // 机构信息id
            setIfNull(dataObject, "orgId", orgInfoId);
        }
    }

    private static void setIfNull(Object target, String property, Object value) {
        try {
            String getterName = "get" + Character.toUpperCase(property.charAt(0)) + property.substring(1);
            Method getter = target.getClass().getMethod(getterName);
            if (getter.invoke(target) != null) {
                return;
            }
            String setterName = "set" + Character.toUpperCase(property.charAt(0)) + property.substring(1);
            Method setter = target.getClass().getMethod(setterName, value.getClass());
            setter.invoke(target, value);
        }
        catch (ReflectiveOperationException ignored) {
            // 非 GBS 标准 DO 忽略
        }
    }

    public static void applyIgnoreOrgId(Object dataObject) {
        if (dataObject == null) {
            return;
        }
        LocalDateTime now = LocalDateTime.now();

        // 常量默认值
        setIfNull(dataObject, "deleteEnum", DELETE_NOT_DELETED);
        setIfNull(dataObject, "env", DEFAULT_ENV);
        setIfNull(dataObject, "version", 0);

        // 时间字段
        setIfNull(dataObject, "createTime", now);
        setIfNull(dataObject, "updateTime", now);

        // 用户上下文字段：从 AuthUserContextAdapter 获取
        Long userId = AuthUserContextAdapter.getCurrentUserId();
        String userName = AuthUserContextAdapter.getCurrentUserName();
        Long tenantId = AuthUserContextAdapter.getCurrentTenantId();


        if (userId != null) {
            setIfNull(dataObject, "createId", userId);
            setIfNull(dataObject, "updateId", userId);
        }
        if (userName != null) {
            setIfNull(dataObject, "createName", userName);
            setIfNull(dataObject, "updateName", userName);
        }
        if (tenantId != null) {
            setIfNull(dataObject, "tenantId", tenantId);
        }
    }
}
