import { OIDCProvider } from '../src/provider';
import { MemoryStorageAdapter } from '../src/storage/memory';
import type { OIDCProviderConfig, OIDCUser, OIDCClient } from '../src/types';

// 示例：带有zod验证的OIDC Provider使用

// 创建存储适配器
const storage = new MemoryStorageAdapter();

// 示例用户查找函数
const findUser = async (userId: string): Promise<OIDCUser | null> => {
    const users: Record<string, OIDCUser> = {
        'user123': {
            sub: 'user123',
            username: 'john@example.com',
            email: 'john@example.com',
            email_verified: true,
            name: 'John Doe',
            given_name: 'John',
            family_name: 'Doe',
        }
    };
    return users[userId] || null;
};

// 示例客户端查找函数
const findClient = async (clientId: string): Promise<OIDCClient | null> => {
    const clients: Record<string, OIDCClient> = {
        'demo-client': {
            client_id: 'demo-client',
            client_secret: 'demo-secret',
            client_name: 'Demo Application',
            client_type: 'confidential',
            redirect_uris: ['https://app.example.com/callback'],
            grant_types: ['authorization_code', 'refresh_token'],
            response_types: ['code'],
            scopes: ['openid', 'profile', 'email'],
            created_at: new Date(),
            updated_at: new Date(),
        }
    };
    return clients[clientId] || null;
};

// 密码验证器
const passwordValidator = async (username: string, password: string): Promise<string | null> => {
    // 这里应该实现真实的密码验证逻辑
    if (username === 'john@example.com' && password === 'password123') {
        return 'user123'; // 返回用户ID
    }
    return null;
};

// 配置OIDC Provider
const config: OIDCProviderConfig = {
    issuer: 'https://auth.example.com',
    signingKey: 'your-secret-key-for-development-only',
    signingAlgorithm: 'HS256',
    storage,
    findUser,
    findClient,
    authConfig: {
        passwordValidator,
        sessionTTL: 3600, // 1小时
        pageConfig: {
            title: 'My Auth Server',
            brandName: 'Example Corp',
            logoUrl: 'https://example.com/logo.png',
        },
        rememberMeMaxAge: 30 * 24 * 3600, // 30天
    },
    tokenTTL: {
        accessToken: 3600, // 1小时
        refreshToken: 30 * 24 * 3600, // 30天
        authorizationCode: 600, // 10分钟
        idToken: 3600, // 1小时
    },
    enablePKCE: true,
    requirePKCE: true, // 对公共客户端强制要求PKCE
    rotateRefreshTokens: true,
};

// 创建OIDC Provider实例
const provider = new OIDCProvider(config);

// 导出配置好的provider
export { provider };

// 使用示例：
// 1. 授权请求会自动使用zod验证所有参数
// 2. 令牌请求会验证FormData和Basic认证头
// 3. 用户信息请求会验证Bearer token格式
// 4. 令牌撤销和内省请求会验证相应的参数

// 错误处理示例：
export const handleAuthorizationExample = async (query: Record<string, string>) => {
    try {
        // 这会触发zod验证
        const result = await provider.handleAuthorizationRequest({
            response_type: query.response_type,
            client_id: query.client_id,
            redirect_uri: query.redirect_uri,
            scope: query.scope,
            state: query.state,
            // ... 其他参数
        });

        if (result.success) {
            console.log('授权码:', result.code);
        } else {
            console.error('授权失败:', result.error);
        }
    } catch (error) {
        if (error instanceof Error && error.message.includes('授权请求参数无效')) {
            console.error('参数验证失败:', error.message);
        } else {
            console.error('未知错误:', error);
        }
    }
};

// 令牌请求示例
export const handleTokenExample = async (formData: FormData) => {
    try {
        // 这会触发zod验证FormData
        const result = await provider.handleTokenRequest({
            grant_type: formData.get('grant_type')?.toString() || '',
            client_id: formData.get('client_id')?.toString() || '',
            // ... 其他参数会被自动验证
        });

        if (result.success) {
            console.log('访问令牌:', result.response.access_token);
        } else {
            console.error('令牌请求失败:', result.error);
        }
    } catch (error) {
        if (error instanceof Error && error.message.includes('令牌请求参数无效')) {
            console.error('参数验证失败:', error.message);
        } else {
            console.error('未知错误:', error);
        }
    }
}; 