package com.mosquito.project.config;

import com.mosquito.project.persistence.repository.ApiKeyRepository;
import com.mosquito.project.security.UserIntrospectionService;
import com.mosquito.project.web.UserAuthInterceptor;
import com.mosquito.project.web.PermissionInterceptor;
import com.mosquito.project.web.AuditInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final com.mosquito.project.web.ApiKeyAuthInterceptor apiKeyAuthInterceptor;
    private final com.mosquito.project.web.RateLimitInterceptor rateLimitInterceptor;
    private final com.mosquito.project.web.ApiResponseWrapperInterceptor responseWrapperInterceptor;
    private final UserAuthInterceptor userAuthInterceptor;
    private final com.mosquito.project.web.AdminCacheRateLimitInterceptor adminCacheRateLimitInterceptor;
    private final PermissionInterceptor permissionInterceptor;
    private final AuditInterceptor auditInterceptor;
    private final org.springframework.core.env.Environment env;

    public WebMvcConfig(ApiKeyRepository apiKeyRepository, org.springframework.core.env.Environment env,
                        java.util.Optional<StringRedisTemplate> redisTemplateOpt,
                        com.mosquito.project.web.ApiResponseWrapperInterceptor responseWrapperInterceptor,
                        UserIntrospectionService userIntrospectionService,
                        AppConfig appConfig,
                        com.mosquito.project.permission.PermissionCheckService permissionCheckService,
                        com.mosquito.project.service.AuditService auditService,
                        com.mosquito.project.service.AuthService authService) {
        this.env = env;
        this.apiKeyAuthInterceptor = new com.mosquito.project.web.ApiKeyAuthInterceptor(apiKeyRepository);
        this.rateLimitInterceptor = new com.mosquito.project.web.RateLimitInterceptor(env, redisTemplateOpt);
        this.responseWrapperInterceptor = responseWrapperInterceptor;
        this.userAuthInterceptor = new UserAuthInterceptor(authService);
        this.adminCacheRateLimitInterceptor = new com.mosquito.project.web.AdminCacheRateLimitInterceptor(
            appConfig, redisTemplateOpt);
        this.permissionInterceptor = new PermissionInterceptor(permissionCheckService);
        this.auditInterceptor = new AuditInterceptor(auditService);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        String allowedOrigins = env.getProperty("app.cors.allowed-origins",
            "http://localhost:5173,http://localhost:3000,http://localhost:8080");
        String allowedMethods = env.getProperty("app.cors.allowed-methods",
            "GET,POST,PUT,DELETE,PATCH,OPTIONS");
        String allowedHeaders = env.getProperty("app.cors.allowed-headers",
            "Content-Type,Authorization,X-API-Key,X-Requested-With,Accept,Origin");
        boolean allowCredentials = Boolean.parseBoolean(env.getProperty("app.cors.allow-credentials", "true"));
        long maxAge = Long.parseLong(env.getProperty("app.cors.max-age", "3600"));

        registry.addMapping("/**")
            .allowedOrigins(allowedOrigins.split(","))
            .allowedMethods(allowedMethods.split(","))
            .allowedHeaders(allowedHeaders.split(","))
            .allowCredentials(allowCredentials)
            .maxAge(maxAge);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 响应包装拦截器 - 所有API
        registry.addInterceptor(responseWrapperInterceptor)
            .addPathPatterns("/api/**");

        // API Key认证拦截器 - 只对外部用户端API生效
        // 排除：管理后台接口(/api/v1/roles, /api/v1/departments, /api/v1/approval等)、回调接口、actuator
        registry.addInterceptor(apiKeyAuthInterceptor)
            .addPathPatterns("/api/v1/callback/**", "/api/v1/share/**")
            .excludePathPatterns(
                "/r/**",
                "/actuator/**",
                // 管理后台接口使用JWT认证，不使用API Key
                "/api/v1/roles/**",
                "/api/v1/departments/**",
                "/api/v1/approval/**",
                "/api/v1/users/**",
                "/api/v1/permissions/**",
                "/api/v1/activities/admin/**",
                "/api/v1/rewards/admin/**",
                "/api/v1/risks/**",
                "/api/v1/audit/**",
                "/api/v1/system/**"
            );

        // 限流拦截器
        registry.addInterceptor(rateLimitInterceptor)
            .addPathPatterns("/api/v1/callback/register");

        // 缓存操作专属限流拦截器
        registry.addInterceptor(adminCacheRateLimitInterceptor)
            .addPathPatterns("/api/v1/system/cache/clear", "/api/v1/system/cache/evict");

        // JWT用户认证拦截器 - 用户端和管理后台通用
        registry.addInterceptor(userAuthInterceptor)
            .addPathPatterns(
                // 用户端API
                "/api/v1/me/**",
                "/api/v1/activities/**",
                "/api/v1/share/**",
                // 管理后台API - 使用JWT认证
                "/api/v1/roles/**",
                "/api/v1/departments/**",
                "/api/v1/approval/**",
                "/api/v1/users/**",
                "/api/v1/invites/**",
                "/api/v1/notifications/**",
                "/api/v1/activities/admin/**",
                "/api/v1/rewards/admin/**",
                "/api/v1/risks/**",
                "/api/v1/audit/**",
                "/api/v1/system/**",
                "/api/v1/dashboard/**",
                "/api/v1/keys/**"
            );

        // 权限校验拦截器 - 对标注了 @RequirePermission 的方法进行权限校验
        // 应该在JWT认证拦截器之后执行
        registry.addInterceptor(permissionInterceptor)
            .addPathPatterns(
                // 管理后台API
                "/api/v1/roles/**",
                "/api/v1/departments/**",
                "/api/v1/approval/**",
                "/api/v1/users/**",
                "/api/v1/permissions/**",
                "/api/v1/invites/**",
                "/api/v1/notifications/**",
                // 活动管理API - 核心管理接口需要权限拦截
                "/api/v1/activities/**",
                "/api/v1/activities/admin/**",
                "/api/v1/rewards/admin/**",
                "/api/v1/risks/**",
                "/api/v1/audit/**",
                "/api/v1/system/**",
                "/api/v1/dashboard/**",
                // API Key管理接口需要权限拦截
                "/api/v1/keys/**"
            )
            .excludePathPatterns(
                // 外部回调接口使用API Key认证，不进行权限校验
                "/api/v1/callback/**",
                // 分享链接接口使用API Key认证
                "/api/v1/share/**"
            );

        // 审计日志拦截器 - 自动记录关键操作
        registry.addInterceptor(auditInterceptor)
            .addPathPatterns("/api/**")
            .excludePathPatterns(
                "/api/v1/share/**",
                "/r/**"
            );
    }
}
