package com.xly.erp.common.security;

import com.xly.erp.common.config.StubSecurityProperties;
import com.xly.erp.common.exception.BizException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Date;

@Component
public class JwtUtil {

    public static final Duration ACCESS_TTL = Duration.ofHours(8);
    public static final Duration REFRESH_TTL = Duration.ofDays(30);

    private final SecretKey key;

    public JwtUtil(String secret) {
        this.key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
    }

    @Autowired
    public JwtUtil(StubSecurityProperties props) {
        this(props.getJwtSecret());
    }

    public String sign(String userNo) {
        return sign(userNo, ACCESS_TTL);
    }

    public String signRefresh(String userNo) {
        return sign(userNo, REFRESH_TTL);
    }

    public String sign(String userNo, Duration ttl) {
        Date now = new Date();
        return Jwts.builder()
                .subject(userNo)
                .issuedAt(now)
                .expiration(new Date(now.getTime() + ttl.toMillis()))
                .signWith(key)
                .compact();
    }

    public String parse(String token) {
        try {
            return Jwts.parser()
                    .verifyWith(key)
                    .build()
                    .parseSignedClaims(token)
                    .getPayload()
                    .getSubject();
        } catch (JwtException | IllegalArgumentException e) {
            throw new BizException(20001, "未认证或 token 已失效");
        }
    }
}
