package tech.easyflow.ai.service.impl;

import com.mybatisflex.core.query.QueryWrapper;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import tech.easyflow.ai.entity.Plugin;
import tech.easyflow.ai.mapper.PluginCategoryMappingMapper;
import tech.easyflow.ai.mapper.PluginMapper;
import tech.easyflow.system.entity.vo.RoleCategoryAccessSnapshot;
import tech.easyflow.system.service.CategoryPermissionService;

import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * 插件分类分页查询测试。
 */
public class PluginServicePageQueryTest {

    /**
     * 验证具体分类下仍会按插件名称过滤。
     */
    @Test
    public void shouldFilterCategorizedPluginsByName() {
        PluginMapper pluginMapper = mock(PluginMapper.class);
        PluginCategoryMappingMapper mappingMapper = mock(PluginCategoryMappingMapper.class);
        CategoryPermissionService categoryPermissionService = mock(CategoryPermissionService.class);
        RoleCategoryAccessSnapshot access = mock(RoleCategoryAccessSnapshot.class);
        PluginServiceImpl service = new PluginServiceImpl();
        service.pluginMapper = pluginMapper;
        service.pluginCategoryMappingMapper = mappingMapper;
        setField(service, "categoryPermissionService", categoryPermissionService);

        when(categoryPermissionService.getCurrentAccess("PLUGIN")).thenReturn(access);
        when(access.isRestricted()).thenReturn(false);
        when(mappingMapper.selectListByQueryAs(any(QueryWrapper.class), eq(BigInteger.class)))
                .thenReturn(List.of(BigInteger.ONE));
        when(pluginMapper.selectListWithRelationsByQuery(any(QueryWrapper.class)))
                .thenReturn(Collections.emptyList());

        service.pageByCategory(1L, 12L, 7, " 1213 ");

        ArgumentCaptor<QueryWrapper> queryCaptor = ArgumentCaptor.forClass(QueryWrapper.class);
        verify(pluginMapper).selectListWithRelationsByQuery(queryCaptor.capture());
        String sql = queryCaptor.getValue().toSQL().toLowerCase(Locale.ROOT);
        Assert.assertTrue(sql.contains("name"));
        Assert.assertTrue(sql.contains("like"));
        Assert.assertTrue(sql.contains("1213"));
    }

    /**
     * 通过反射设置私有依赖。
     *
     * @param target 目标对象
     * @param fieldName 字段名称
     * @param value 字段值
     */
    private static void setField(Object target, String fieldName, Object value) {
        Class<?> current = target.getClass();
        while (current != null) {
            try {
                java.lang.reflect.Field field = current.getDeclaredField(fieldName);
                field.setAccessible(true);
                field.set(target, value);
                return;
            } catch (NoSuchFieldException ignored) {
                current = current.getSuperclass();
            } catch (IllegalAccessException e) {
                throw new IllegalStateException("设置测试字段失败: " + fieldName, e);
            }
        }
        throw new IllegalArgumentException("未找到字段: " + fieldName);
    }
}
