import fs  from 'fs';
import path from 'path';
import { getJWTToken, COZE_CN_BASE_URL } from '@coze/api';
export class CorzAuthorization {
    private accessToken: string | null |undefined;
    private expiresAt: number = 0;
    private pemfile: string;
    private secret: string;
    private sessionName: string;
    constructor(private appid: string,setting:Record<string,any>) {
        this.secret = setting["keyid"];
        this.pemfile = setting["pemfile"] ||  "private.pem"
        this.sessionName = setting["sessionName"] || "default";
    }
    /**
     * 获取授权令牌
     * @returns 
     */
    async getAccessToken():Promise<string|null> {
        // 检查令牌是否存在且未过期,如果有效直接放回
        if (this.accessToken && Date.now() < this.expiresAt) return this.accessToken;
        // 开始新的授权
        const result = await this.doAuthorize();
        if (!result.successed) return null;
        // 缓存授权令牌和过期时间
        this.accessToken = result.accessToken!;
        // 将 expires_in 转换为绝对时间戳
        this.expiresAt = result.expires_in! * 1000; // 将秒转换为毫秒
        return this.accessToken;
    }
    /**
     * 进行授权
     * @returns 
     */
    private async doAuthorize(): Promise<{ successed: boolean, accessToken?: string, expires_in?: number,error?:any }> {
        try {
            // 提取您的 COZE API 授权参数
            //const keyid = "H7rAk-5s0TPOs9-rXnCr7pvkPhpJZGArT__UuMyhbkg";
            const aud = "api.coze.cn";
            // 读取私钥
            const fileFullPath =path.join(process.cwd(), this.pemfile);
            if (!fs.existsSync(fileFullPath)) return { successed: false, error: `${fileFullPath} not existed`}
            const privateKey = fs.readFileSync(fileFullPath).toString();

            // 获取JWT令牌
            const result = await getJWTToken({
                baseURL: COZE_CN_BASE_URL,
                appId:this.appid,
                aud,
                keyid:this.secret,
                privateKey,
                sessionName:this.sessionName,
            });
            return {successed: true, accessToken: result.access_token, expires_in: result.expires_in}
        } catch (error) {
            return { successed: true, error }
        } 
    }
}