package cn.iocoder.byzs.framework.tenant.core.security;

import cn.iocoder.byzs.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.byzs.framework.web.core.util.WebFrameworkUtils;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;

/**
 * 自定义租户行拦截器，解决多表联查时tenant_id字段歧义问题
 */
@Slf4j
public class CustomTenantLineInnerInterceptor extends TenantLineInnerInterceptor {

    public CustomTenantLineInnerInterceptor(TenantLineHandler tenantLineHandler) {
        super(tenantLineHandler);
    }


    /**
     * 重写buildTableExpression方法，解决列歧义问题
     */
    @Override
    public Expression buildTableExpression(Table table, Expression where, String whereSegment) {
        log.info("table:{}, where:{}, whereSegment:{}", table.getName(), where, whereSegment);
        Expression expression = super.buildTableExpression(table, where, whereSegment);

        // 不拼接sql
        if (expression == null) {
            return expression;
        }
        if (TenantContextHolder.isSplice()) {
            return new EqualsTo(this.getAliasColumn(table), this.getTenantLineHandler().getTenantId());
        }

        String column = "";
        //去除表明的别名
        if (table.getAlias() != null) {
            column = table.getAlias().getName() + "." ;
        }
        column += WebFrameworkUtils.HEADER_DATA_TENANT_ID;
        Long currentTenantId = TenantContextHolder.getRequiredTenantId();
        // 构造 JSQLParser 兼容的列表达式
        Column tenantIdColumn = new Column(column);
        EqualsTo condition1 = new EqualsTo(tenantIdColumn, new LongValue(currentTenantId));
        EqualsTo condition2 = new EqualsTo(tenantIdColumn, new LongValue(1L));

        // 用 ParenthesedExpressionList 包裹 OR 表达式添加括号
        OrExpression orExpression = new OrExpression(condition1, condition2);
        return new ParenthesedExpressionList<>(orExpression); // 生成 (A OR B)
    }
}