package com.ruoyi.web.modules.industryservice.support;

import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;

/**
 * 产业填报类列表/导出的部门数据范围：
 * <ul>
 *   <li>超级管理员：不过滤</li>
 *   <li>其余用户（含角色「全部数据权限」）：一律按本部门及下级过滤
 *       （乡镇用户可见本镇各村；村用户仅本村）</li>
 * </ul>
 * 通过业务表 {@code town_dept_id}/{@code village_dept_id} 与 {@code sys_dept.ancestors} 匹配。
 * <p>
 * 说明：不沿用角色 data_scope=全部。否则多角色时乡镇下拉（@DataScope 按菜单权限匹配）已收窄，
 * 列表却因另一角色「全部」而仍能看到外镇数据。
 */
public final class ReportDeptDataScopeSupport
{
    public static final String PARAM_KEY = "dataScope";

    private ReportDeptDataScopeSupport()
    {
    }

    /**
     * @param query 查询对象（写入 params.dataScope）
     * @param tableAlias 业务表别名，如 h / r
     */
    public static void apply(BaseEntity query, String tableAlias)
    {
        boolean admin = SecurityUtils.isAdmin();
        SysUser user = null;
        Long deptId = null;
        if (!admin)
        {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            user = loginUser != null ? loginUser.getUser() : null;
            if (loginUser != null)
            {
                deptId = loginUser.getDeptId();
            }
            if (deptId == null && user != null)
            {
                deptId = user.getDeptId();
            }
        }
        apply(query, tableAlias, admin, user, deptId);
    }

    /**
     * 便于单测注入用户上下文。
     */
    static void apply(BaseEntity query, String tableAlias, boolean admin, SysUser user)
    {
        Long deptId = user != null ? user.getDeptId() : null;
        apply(query, tableAlias, admin, user, deptId);
    }

    static void apply(BaseEntity query, String tableAlias, boolean admin, SysUser user, Long deptId)
    {
        if (query == null)
        {
            return;
        }
        query.getParams().put(PARAM_KEY, "");
        if (StringUtils.isEmpty(tableAlias))
        {
            return;
        }
        if (admin)
        {
            return;
        }
        if (user == null)
        {
            query.getParams().put(PARAM_KEY, " AND 1=0 ");
            return;
        }
        if (deptId == null)
        {
            query.getParams().put(PARAM_KEY, " AND 1=0 ");
            return;
        }
        String sql = StringUtils.format(
                " AND ({}.village_dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} OR find_in_set( {} , ancestors ) )"
                        + " OR {}.town_dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} OR find_in_set( {} , ancestors ) ))",
                tableAlias, deptId, deptId, tableAlias, deptId, deptId);
        query.getParams().put(PARAM_KEY, sql);
    }
}
