import type {
    AuthorizationCode,
    AccessToken,
    RefreshToken,
    IDToken,
} from '../types';
import type { StorageAdapter } from '../storage';

/**
 * 令牌管理器
 * 处理所有令牌相关的存储业务逻辑
 */
export class TokenManager {
    constructor(private storage: StorageAdapter) { }

    /**
     * 计算TTL（秒）
     */
    private calculateTTL(expiresAt: Date): number {
        return Math.max(Math.floor((expiresAt.getTime() - Date.now()) / 1000), 1);
    }

    // 生成令牌存储键
    private getTokenKey(type: string, token: string): string {
        return `${type}:${token}`;
    }

    private getUserClientKey(type: string, userId: string, clientId: string): string {
        return `${type}:user:${userId}:client:${clientId}`;
    }

    // 授权码管理
    async storeAuthorizationCode(authCode: AuthorizationCode): Promise<void> {
        const key = this.getTokenKey('auth_code', authCode.code);
        const ttl = this.calculateTTL(authCode.expires_at);
        await this.storage.set(key, authCode, ttl);
    }

    async getAuthorizationCode(code: string): Promise<AuthorizationCode | null> {
        const key = this.getTokenKey('auth_code', code);
        return await this.storage.get<AuthorizationCode>(key);
    }

    async deleteAuthorizationCode(code: string): Promise<void> {
        const key = this.getTokenKey('auth_code', code);
        await this.storage.delete(key);
    }

    // 访问令牌管理
    async storeAccessToken(token: AccessToken): Promise<void> {
        const key = this.getTokenKey('access_token', token.token);
        const userClientKey = this.getUserClientKey('access_tokens', token.user_id, token.client_id);
        const ttl = this.calculateTTL(token.expires_at);

        // 存储令牌数据
        await this.storage.set(key, token, ttl);

        // 存储用户-客户端索引
        const existingTokens = await this.storage.get<string[]>(userClientKey) || [];
        existingTokens.push(token.token);
        await this.storage.set(userClientKey, existingTokens, ttl);
    }

    async getAccessToken(token: string): Promise<AccessToken | null> {
        const key = this.getTokenKey('access_token', token);
        return await this.storage.get<AccessToken>(key);
    }

    async deleteAccessToken(token: string): Promise<void> {
        const key = this.getTokenKey('access_token', token);

        // 获取令牌数据以清理索引
        const tokenData = await this.storage.get(key);
        if (tokenData) {
            const userClientKey = this.getUserClientKey('access_tokens', tokenData.user_id, tokenData.client_id);
            const tokens = await this.storage.get<string[]>(userClientKey) || [];
            const filteredTokens = tokens.filter(t => t !== token);

            if (filteredTokens.length > 0) {
                await this.storage.set(userClientKey, filteredTokens);
            } else {
                await this.storage.delete(userClientKey);
            }
        }

        await this.storage.delete(key);
    }

    async deleteAccessTokensByUserAndClient(userId: string, clientId: string): Promise<void> {
        const userClientKey = this.getUserClientKey('access_tokens', userId, clientId);
        const tokens = await this.storage.get<string[]>(userClientKey) || [];

        // 删除所有相关令牌
        for (const token of tokens) {
            await this.storage.delete(this.getTokenKey('access_token', token));
        }

        // 删除索引
        await this.storage.delete(userClientKey);
    }

    // 刷新令牌管理
    async storeRefreshToken(token: RefreshToken): Promise<void> {
        const key = this.getTokenKey('refresh_token', token.token);
        const userClientKey = this.getUserClientKey('refresh_tokens', token.user_id, token.client_id);
        const ttl = this.calculateTTL(token.expires_at);

        // 存储令牌数据
        await this.storage.set(key, token, ttl);

        // 存储用户-客户端索引
        const existingTokens = await this.storage.get<string[]>(userClientKey) || [];
        existingTokens.push(token.token);
        await this.storage.set(userClientKey, existingTokens, ttl);
    }

    async getRefreshToken(token: string): Promise<RefreshToken | null> {
        const key = this.getTokenKey('refresh_token', token);
        return await this.storage.get<RefreshToken>(key);
    }

    async deleteRefreshToken(token: string): Promise<void> {
        const key = this.getTokenKey('refresh_token', token);

        // 获取令牌数据以清理索引
        const tokenData = await this.storage.get(key);
        if (tokenData) {
            const userClientKey = this.getUserClientKey('refresh_tokens', tokenData.user_id, tokenData.client_id);
            const tokens = await this.storage.get<string[]>(userClientKey) || [];
            const filteredTokens = tokens.filter(t => t !== token);

            if (filteredTokens.length > 0) {
                await this.storage.set(userClientKey, filteredTokens);
            } else {
                await this.storage.delete(userClientKey);
            }
        }

        await this.storage.delete(key);
    }

    // ID令牌管理
    async storeIDToken(token: IDToken): Promise<void> {
        const key = this.getTokenKey('id_token', token.token);
        const ttl = this.calculateTTL(token.expires_at);
        await this.storage.set(key, token, ttl);
    }

    async getIDToken(token: string): Promise<IDToken | null> {
        const key = this.getTokenKey('id_token', token);
        return await this.storage.get<IDToken>(key);
    }

    async deleteIDToken(token: string): Promise<void> {
        const key = this.getTokenKey('id_token', token);
        await this.storage.delete(key);
    }
} 