package com.njcn.msgpush.module.push.filter;

/**
 * @author caozehui
 * @data 2026-03-31
 */

import cn.hutool.core.util.StrUtil;
import com.njcn.msgpush.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.njcn.msgpush.framework.common.pojo.CommonResult;
import com.njcn.msgpush.framework.common.util.servlet.ServletUtils;
import com.njcn.msgpush.framework.web.config.WebProperties;
import com.njcn.msgpush.framework.web.core.filter.ApiRequestFilter;
import com.njcn.msgpush.module.push.service.credential.CredentialServiceImpl;
import com.njcn.msgpush.module.push.service.credential.ICredentialService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 凭证认证过滤器
 *
 * @author msgpush
 */
@Component
@Slf4j
public class CredentialAuthenticationFilter extends ApiRequestFilter implements Ordered {

    @Autowired
    private ICredentialService credentialService;

    /**
     * 凭证 Header 名称
     */
    private static final String CREDENTIAL_HEADER = "X-Credential-Token";

    /**
     * 需要凭证认证的接口路径
     */
    private static final String[] NOT_IGNORE_PATHS = {
            "/admin-api/push/message/send/**",
    };

    private static final String[] IGNORE_PATHS = {
            "/admin-api/push/credential/generate",
    };

    public CredentialAuthenticationFilter(WebProperties webProperties) {
        super(webProperties);
    }


    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        // 检查是否在排除列表中
        String path = request.getRequestURI().substring(request.getContextPath().length());
        for (String notExcludePath : NOT_IGNORE_PATHS) {
            if (path.equals(notExcludePath)) {
                return false;
            }
            if (notExcludePath.endsWith("/**") && path.startsWith(notExcludePath.substring(0, notExcludePath.length() - 3))) {
                return false;
            }
        }
        for (String excludePath : IGNORE_PATHS){
            if (path.equals(excludePath)) {
                return true;
            }
            if (excludePath.endsWith("/**") && path.startsWith(excludePath.substring(0, excludePath.length() - 3))) {
                return true;
            }
        }

        return super.shouldNotFilter(request);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 1. 获取凭证 token
        String credentialToken = request.getHeader(CREDENTIAL_HEADER);
        if (StrUtil.isEmpty(credentialToken)) {
            credentialToken = request.getParameter("credential");
        }

        // 2. 如果没有凭证，继续过滤链
        if (StrUtil.isEmpty(credentialToken)) {
            ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "缺少凭证"));
            return;
        }

        // 3. 验证凭证
        CredentialServiceImpl.CredentialInfo credentialInfo = credentialService.verifyCredential(credentialToken);

        if (credentialInfo == null) {
            // 校验失败
            ServletUtils.writeJSON(response, CommonResult.error(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "凭证无效或已过期"));
            return;
        }

        filterChain.doFilter(request, response);
    }


    @Override
    public int getOrder() {
        return 1000;
    }
}
