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

import java.util.Date;
import org.springframework.stereotype.Component;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.industryservice.research.config.ResearchOpenApiProperties;
import com.ruoyi.web.modules.industryservice.research.domain.dto.ResearchTokenVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * 科研开放接口 Token 签发与校验（独立于若依用户 JWT）。
 */
@Component
public class ResearchOpenApiTokenService
{
    private final ResearchOpenApiProperties properties;

    public ResearchOpenApiTokenService(ResearchOpenApiProperties properties)
    {
        this.properties = properties;
    }

    public ResearchTokenVo issueToken(String appKey, String appSecret)
    {
        assertEnabled();
        assertCredentials(appKey, appSecret);
        long expireSeconds = properties.getTokenExpireMinutes() * 60L;
        Date now = new Date();
        Date expireAt = new Date(now.getTime() + expireSeconds * 1000L);
        String token = Jwts.builder()
                .claim("type", ResearchOpenApiConstants.TOKEN_TYPE)
                .setIssuedAt(now)
                .setExpiration(expireAt)
                .signWith(SignatureAlgorithm.HS512, properties.getTokenSecret())
                .compact();
        ResearchTokenVo vo = new ResearchTokenVo();
        vo.setAccessToken(token);
        vo.setTokenType("Bearer");
        vo.setExpiresIn(expireSeconds);
        return vo;
    }

    public void validateToken(String token)
    {
        assertEnabled();
        if (StringUtils.isEmpty(token))
        {
            throw new ServiceException("缺少访问令牌", 401);
        }
        try
        {
            Claims claims = Jwts.parser()
                    .setSigningKey(properties.getTokenSecret())
                    .parseClaimsJws(token)
                    .getBody();
            if (!ResearchOpenApiConstants.TOKEN_TYPE.equals(claims.get("type")))
            {
                throw new ServiceException("无效的访问令牌", 401);
            }
        }
        catch (ServiceException ex)
        {
            throw ex;
        }
        catch (Exception ex)
        {
            throw new ServiceException("访问令牌已失效或无效", 401);
        }
    }

    public void assertEnabled()
    {
        if (!properties.isEnabled())
        {
            throw new ServiceException("科研开放接口未启用", 503);
        }
    }

    private void assertCredentials(String appKey, String appSecret)
    {
        if (StringUtils.isEmpty(properties.getAppKey()) || StringUtils.isEmpty(properties.getAppSecret()))
        {
            throw new ServiceException("科研开放接口未配置 appKey/appSecret", 503);
        }
        if (!properties.getAppKey().equals(appKey) || !properties.getAppSecret().equals(appSecret))
        {
            throw new ServiceException("appKey 或 appSecret 无效", 401);
        }
    }
}
