import { z } from 'zod';
import { ApiResponseSchema } from '#contracts/shared';

// ---------------------------------------------------------------------------
// Token response (from /oauth/token)
// ---------------------------------------------------------------------------

export const TokenResponseSchema = z
	.object({
		access_token: z.string(),
		token_type: z.string().default('Bearer'),
		expires_in: z.number(),
		refresh_token: z.string().optional(),
		id_token: z.string().optional(),
		scope: z.string().optional(),
	})
	.openapi('TokenResponse');

export const TokenResponseWrapperSchema = ApiResponseSchema(TokenResponseSchema).openapi('TokenResponseWrapper');

// ---------------------------------------------------------------------------
// Token introspection
// ---------------------------------------------------------------------------

export const IntrospectionRequestSchema = z
	.object({
		token: z.string(),
		token_type_hint: z.enum(['access_token', 'refresh_token']).optional(),
	})
	.openapi('IntrospectionRequest');

export const IntrospectionResponseSchema = z
	.object({
		active: z.boolean(),
		scope: z.string().optional(),
		client_id: z.string().optional(),
		username: z.string().optional(),
		token_type: z.string().optional(),
		exp: z.number().optional(),
		iat: z.number().optional(),
		sub: z.string().optional(),
		aud: z.union([z.string(), z.array(z.string())]).optional(),
		iss: z.string().optional(),
	})
	.openapi('IntrospectionResponse');

// ---------------------------------------------------------------------------
// Revocation
// ---------------------------------------------------------------------------

export const RevocationRequestSchema = z
	.object({
		token: z.string(),
		token_type_hint: z.enum(['access_token', 'refresh_token']).optional(),
	})
	.openapi('RevocationRequest');

// ---------------------------------------------------------------------------
// UserInfo
// ---------------------------------------------------------------------------

export const UserInfoResponseSchema = z
	.object({
		sub: z.string().openapi({ description: 'Subject identifier (user ID)', example: '550e8400-e29b-41d4-a716-446655440000' }),
		name: z.string().optional().openapi({ example: 'John Doe' }),
		preferred_username: z.string().optional().openapi({ example: 'johndoe' }),
		email: z.string().email().optional().openapi({ example: 'johndoe@example.com' }),
		email_verified: z.boolean().optional().default(false).openapi({ example: false }),
	})
	.openapi('UserInfoResponse');

// ---------------------------------------------------------------------------
// OIDC discovery
// ---------------------------------------------------------------------------

export const OIDCDiscoverySchema = z.object({}).passthrough().openapi('OIDCDiscovery');

// ---------------------------------------------------------------------------
// Error responses
// ---------------------------------------------------------------------------

export const OAuthErrorResponseSchema = z
	.object({
		error: z.enum([
			'invalid_request',
			'invalid_client',
			'invalid_grant',
			'unauthorized_client',
			'unsupported_grant_type',
			'server_error',
			'temporarily_unavailable',
		]),
		error_description: z.string().optional(),
	})
	.openapi('OAuthError');

export const OIDCErrorResponseSchema = z
	.object({
		error: z.string(),
		error_description: z.string().optional(),
	})
	.openapi('OIDCError');
