package com.mosquito.project.config;

import com.mosquito.project.persistence.entity.ApiKeyEntity;
import com.mosquito.project.persistence.repository.ActivityRepository;
import com.mosquito.project.persistence.repository.ApiKeyRepository;
import com.mosquito.project.persistence.repository.LinkClickRepository;
import com.mosquito.project.persistence.repository.SysAuditLogRepository;
import com.mosquito.project.persistence.repository.UserInviteRepository;
import com.mosquito.project.persistence.repository.UserRewardRepository;
import com.mosquito.project.permission.ApprovalFlowService;
import com.mosquito.project.permission.*;
import com.mosquito.project.security.IntrospectionResponse;
import com.mosquito.project.security.UserIntrospectionService;
import com.mosquito.project.service.*;
import com.mosquito.project.support.TestAuthSupport;
import org.mockito.Mockito;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;

import java.util.List;
import java.util.Optional;

@TestConfiguration
@Import(TestSecurityConfig.class)
public class ControllerTestConfig {

    @Bean
    @Primary
    public ActivityService activityService() {
        return Mockito.mock(ActivityService.class);
    }

    @Bean
    @Primary
    public ShareTrackingService shareTrackingService() {
        return Mockito.mock(ShareTrackingService.class);
    }

    @Bean
    @Primary
    public ShareConfigService shareConfigService() {
        return Mockito.mock(ShareConfigService.class);
    }

    @Bean
    @Primary
    public PosterRenderService posterRenderService() {
        return Mockito.mock(PosterRenderService.class);
    }

    @Bean
    @Primary
    public ShortLinkService shortLinkService() {
        return Mockito.mock(ShortLinkService.class);
    }

    @Bean
    @Primary
    public LinkClickRepository linkClickRepository() {
        return Mockito.mock(LinkClickRepository.class);
    }

    @Bean
    @Primary
    public ActivityRepository activityRepository() {
        return Mockito.mock(ActivityRepository.class);
    }

    @Bean
    @Primary
    public ApiKeyRepository apiKeyRepository() {
        ApiKeyRepository repository = Mockito.mock(ApiKeyRepository.class);
        ApiKeyEntity apiKeyEntity = TestAuthSupport.buildApiKeyEntity();
        Mockito.when(repository.findByKeyPrefix(TestAuthSupport.API_KEY_PREFIX))
            .thenReturn(Optional.of(apiKeyEntity));
        return repository;
    }

    @Bean
    @Primary
    public UserInviteRepository userInviteRepository() {
        return Mockito.mock(UserInviteRepository.class);
    }

    @Bean
    @Primary
    public UserRewardRepository userRewardRepository() {
        return Mockito.mock(UserRewardRepository.class);
    }

    @Bean
    @Primary
    public UserIntrospectionService userIntrospectionService() {
        UserIntrospectionService service = Mockito.mock(UserIntrospectionService.class);
        IntrospectionResponse response = new IntrospectionResponse();
        response.setActive(true);
        response.setUserId("1");  // 设置测试用户ID
        response.setRoles(List.of("super_admin"));  // 设置测试角色
        response.setExp(System.currentTimeMillis() / 1000 + 3600);  // 设置过期时间
        response.setJti("test-jti-001");
        Mockito.when(service.introspect(Mockito.anyString())).thenReturn(response);
        return service;
    }

    @Bean
    @Primary
    public AppConfig appConfig() {
        return new AppConfig();
    }

    @Bean
    @Primary
    public RoleRepository roleRepository() {
        return Mockito.mock(RoleRepository.class);
    }

    @Bean
    @Primary
    public PermissionRepository permissionRepository() {
        return Mockito.mock(PermissionRepository.class);
    }

    @Bean
    @Primary
    public UserRoleRepository userRoleRepository() {
        return Mockito.mock(UserRoleRepository.class);
    }

    @Bean
    @Primary
    public RolePermissionRepository rolePermissionRepository() {
        return Mockito.mock(RolePermissionRepository.class);
    }

    @Bean
    @Primary
    public PermissionCheckService permissionCheckService() {
        PermissionCheckService service = Mockito.mock(PermissionCheckService.class);
        // 所有权限检查默认返回true，允许测试通过
        Mockito.when(service.hasPermission(Mockito.anyLong(), Mockito.anyString())).thenReturn(true);
        Mockito.when(service.hasRole(Mockito.anyLong(), Mockito.anyString())).thenReturn(true);
        Mockito.when(service.getUserDataScope(Mockito.anyLong())).thenReturn("ALL");
        // 数据访问权限检查默认返回true
        Mockito.when(service.canAccessData(Mockito.anyLong(), Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(true);
        return service;
    }

    @Bean
    @Primary
    public ApprovalFlowService approvalFlowService() {
        return Mockito.mock(ApprovalFlowService.class);
    }

    @Bean
    @Primary
    public SysAuditLogRepository sysAuditLogRepository() {
        return Mockito.mock(SysAuditLogRepository.class);
    }

    @Bean
    @Primary
    public AuditService auditService() {
        return Mockito.mock(AuditService.class);
    }

    @Bean
    @Primary
    public AuthService authService() {
        AuthService authService = Mockito.mock(AuthService.class);
        // Mock token验证 - 所有带"Bearer test-"前缀的token都视为有效
        Mockito.when(authService.validateToken(Mockito.anyString())).thenAnswer(invocation -> {
            String token = invocation.getArgument(0);
            if (token != null && token.startsWith("Bearer test-")) {
                return new com.mosquito.project.service.AuthService.TokenInfo(1L,
                    java.time.Instant.now().plusSeconds(3600));
            }
            return null;
        });
        // Mock用户信息
        com.mosquito.project.service.AuthService.UserInfo userInfo =
            new com.mosquito.project.service.AuthService.UserInfo(
                1L, "testuser", "hash", "测试用户",
                1L,
                java.util.List.of("super_admin"),
                java.util.List.of("*"));
        Mockito.when(authService.getUserById(1L)).thenReturn(userInfo);
        return authService;
    }
}
