package com.storlead.framework.mybatis.tenant;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 多租户行拦截配置。
 * <p>
 * 默认不对任何表注入 {@code tenant_id}；仅 {@link #includeTables} 中配置的表在 {@link #enabled}=true 时参与租户隔离。
 * </p>
 */
@Data
@ConfigurationProperties(prefix = "storlead.tenant")
public class TenantProperties {

    /**
     * 是否开启多租户 SQL 行拦截与插入填充（false 时所有表均不处理 tenant_id）。
     */
    private boolean enabled = false;

    /**
     * 数据库列名，需与实体字段映射一致（默认 tenant_id）。
     */
    private String columnName = "tenant_id";

    /**
     * 需要租户隔离的表白名单（小写表名，不含库名）。未列入的表不会拼接 tenant_id 条件。
     */
    private List<String> includeTables = new ArrayList<>();

    /**
     * @deprecated 已改为 {@link #includeTables} 白名单模式；仅当 includeTables 为空且本列表非空时，仍按旧黑名单逻辑兼容。
     */
    @Deprecated
    private List<String> ignoreTables = new ArrayList<>();

    /**
     * 不参与租户 SQL 解析的 Mapper 语句（全限定 statementId，或后缀匹配如 HrmresourceMapper.updatePermanentDate）。
     * 多表 JOIN 的 UPDATE/复杂 SELECT 无法被 TenantSqlParser 处理，须排除。
     */
    private List<String> excludeStatementIds = defaultExcludeStatementIds();

    private static List<String> defaultExcludeStatementIds() {
        List<String> ids = new ArrayList<>();
        ids.add("com.storlead.user.mapper.HrmresourceMapper.updatePermanentDate");
        ids.add("com.storlead.user.mapper.HrmresourceMapper.updateResignDate");
        ids.add("com.storlead.user.mapper.HrmresourceMapper.getUserList");
        return ids;
    }

    /**
     * 当前表是否应注入 / 填充 tenant_id。
     */
    public boolean shouldApplyTenantLine(String tableName) {
        if (!enabled || tableName == null) {
            return false;
        }
        String normalized = normalizeTableName(tableName);
        if (!includeTables.isEmpty()) {
            return includeTables.stream().anyMatch(t -> tableNameEquals(normalized, t));
        }
        if (!ignoreTables.isEmpty()) {
            return ignoreTables.stream().noneMatch(t -> tableNameEquals(normalized, t));
        }
        return false;
    }

    /**
     * 是否跳过 MyBatis 租户 SQL 解析（复杂 JOIN / 多表 UPDATE 等）。
     */
    public boolean shouldExcludeStatement(String statementId) {
        if (statementId == null || excludeStatementIds == null || excludeStatementIds.isEmpty()) {
            return false;
        }
        for (String pattern : excludeStatementIds) {
            if (pattern == null || pattern.isEmpty()) {
                continue;
            }
            if (statementId.equals(pattern) || statementId.endsWith("." + pattern)) {
                return true;
            }
        }
        return false;
    }

    public static String normalizeTableName(String tableName) {
        return tableName.replace("`", "").toLowerCase(Locale.ROOT);
    }

    private static boolean tableNameEquals(String normalized, String configured) {
        if (configured == null) {
            return false;
        }
        return normalized.equals(normalizeTableName(configured));
    }
}
