/**
 * TypeScript types for django-allauth headless API
 * Generated from OpenAPI specification
 */

// =============================================================================
// Primitive Types
// =============================================================================

/** Epoch-based timestamp (use: new Date(value * 1000)) */
export type Timestamp = number

/** Email address */
export type Email = string

/** Phone number */
export type Phone = string

/** Username */
export type Username = string

/** Password */
export type Password = string

/** One-time code */
export type Code = string

/** Authenticator code (e.g., TOTP) */
export type AuthenticatorCode = string

/** Provider ID (e.g., "google", "github") */
export type ProviderID = string

/** Provider-specific account ID */
export type ProviderAccountID = string

/** Authenticator ID */
export type AuthenticatorID = number

/** OAuth client ID */
export type ClientID = string

// =============================================================================
// Enums
// =============================================================================

export type AuthenticatorType = 'recovery_codes' | 'totp' | 'webauthn'

export type FlowID =
    | 'login'
    | 'login_by_code'
    | 'mfa_authenticate'
    | 'mfa_reauthenticate'
    | 'provider_redirect'
    | 'provider_signup'
    | 'provider_token'
    | 'reauthenticate'
    | 'signup'
    | 'verify_email'
    | 'verify_phone'

export type LoginMethod = 'email' | 'username'

export type OAuthProcess = 'login' | 'connect'

export type ProviderFlow = 'provider_redirect' | 'provider_token'

// =============================================================================
// User & Session Types
// =============================================================================

export interface User {
    id?: number
    display: string
    email?: string
    username?: string
    has_usable_password: boolean
}

export interface Session {
    id: number
    user_agent: string
    ip: string
    created_at: Timestamp
    last_seen_at?: Timestamp
    is_current: boolean
}

export interface EmailAddress {
    email: Email
    primary: boolean
    verified: boolean
}

export interface PhoneNumber {
    phone: Phone
    verified: boolean
}

// =============================================================================
// Authentication Types
// =============================================================================

export interface Flow {
    id: FlowID
    is_pending?: true
    provider?: Provider
    /** MFA types available (for mfa_authenticate/mfa_reauthenticate flows) */
    types?: AuthenticatorType[]
}

export interface AuthenticationMethod {
    method: 'password' | 'password_reset' | 'code' | 'socialaccount' | 'mfa'
    at: Timestamp
    email?: Email
    phone?: Phone
    username?: Username
    provider?: ProviderID
    uid?: ProviderAccountID
    type?: AuthenticatorType
    reauthenticated?: boolean
}

export interface Authenticated {
    user: User
    methods: AuthenticationMethod[]
}

export interface ReauthenticationRequired {
    flows: Flow[]
    user: User
    methods: AuthenticationMethod[]
}

// =============================================================================
// Provider Types
// =============================================================================

export interface Provider {
    id: ProviderID
    name: string
    client_id?: ClientID
    openid_configuration_url?: string
    flows: ProviderFlow[]
}

export interface ProviderAccount {
    uid: ProviderAccountID
    display: string
    provider: Provider
}

// =============================================================================
// MFA / Authenticator Types
// =============================================================================

export interface BaseAuthenticator {
    created_at: Timestamp
    last_used_at: Timestamp | null
}

export interface TOTPAuthenticator extends BaseAuthenticator {
    type: 'totp'
}

export interface RecoveryCodesAuthenticator extends BaseAuthenticator {
    type: 'recovery_codes'
    total_code_count: number
    unused_code_count: number
}

export interface SensitiveRecoveryCodesAuthenticator extends RecoveryCodesAuthenticator {
    unused_codes: AuthenticatorCode[]
}

export interface WebAuthnAuthenticator extends BaseAuthenticator {
    type: 'webauthn'
    id: AuthenticatorID
    name: string
    is_passwordless?: boolean
}

export type Authenticator = TOTPAuthenticator | RecoveryCodesAuthenticator | WebAuthnAuthenticator

// =============================================================================
// Configuration Types
// =============================================================================

export interface AccountConfiguration {
    login_methods?: LoginMethod[]
    is_open_for_signup: boolean
    email_verification_by_code_enabled: boolean
    login_by_code_enabled: boolean
    password_reset_by_code_enabled?: boolean
}

export interface SocialAccountConfiguration {
    providers: Provider[]
}

export interface MFAConfiguration {
    supported_types: AuthenticatorType[]
    passkey_login_enabled?: boolean
}

export interface UserSessionsConfiguration {
    track_activity: boolean
}

export interface AllauthConfiguration {
    account: AccountConfiguration
    socialaccount?: SocialAccountConfiguration
    mfa?: MFAConfiguration
    usersessions?: UserSessionsConfiguration
}

// =============================================================================
// WebAuthn Types
// =============================================================================

export interface WebAuthnPublicKeyCredentialCreationOptions {
    challenge: string
    rp: {
        name: string
        id: string
    }
    user: {
        id: string
        name: string
        displayName: string
    }
    pubKeyCredParams: Array<{
        type: 'public-key'
        alg: number
    }>
    timeout?: number
    excludeCredentials?: Array<{
        type: 'public-key'
        id: string
    }>
    authenticatorSelection?: {
        authenticatorAttachment?: 'platform' | 'cross-platform'
        requireResidentKey?: boolean
        residentKey?: 'discouraged' | 'preferred' | 'required'
        userVerification?: 'required' | 'preferred' | 'discouraged'
    }
    attestation?: 'none' | 'indirect' | 'direct' | 'enterprise'
}

export interface WebAuthnPublicKeyCredentialRequestOptions {
    challenge: string
    rpId: string
    allowCredentials?: Array<{
        type: 'public-key'
        id: string
    }>
    userVerification?: 'required' | 'preferred' | 'discouraged'
    timeout?: number
}

export interface WebAuthnCreationOptions {
    creation_options: {
        publicKey: WebAuthnPublicKeyCredentialCreationOptions
    }
}

export interface WebAuthnRequestOptions {
    request_options: {
        publicKey: WebAuthnPublicKeyCredentialRequestOptions
    }
}

// =============================================================================
// TOTP Types
// =============================================================================

export interface TOTPStatus {
    type: 'totp'
    created_at: Timestamp
    last_used_at: Timestamp | null
    /** Base32-encoded secret (only present when not yet activated) */
    secret?: string
    /** TOTP URI for QR code generation */
    totp_url?: string
}

// =============================================================================
// API Response Meta Types
// =============================================================================

export interface BaseAuthenticationMeta {
    /** Session token (app clients only) */
    session_token?: string
    /** Access token (app clients only) */
    access_token?: string
}

export interface AuthenticationMeta extends BaseAuthenticationMeta {
    is_authenticated: boolean
}

export interface AuthenticatedMeta extends BaseAuthenticationMeta {
    is_authenticated: true
}

// =============================================================================
// API Response Types
// =============================================================================

export interface AuthError {
    code: string
    message: string
    param?: string
}

/** Base response structure - uses `any` for data/meta to maintain flexibility in generic use */
export interface AllauthResponse<TData = any, TMeta = any> {
    status: number
    data?: TData
    meta?: TMeta
    errors?: AuthError[]
}

/** 200 OK - Authenticated */
export interface AuthenticatedResponse extends AllauthResponse<Authenticated, AuthenticationMeta> {
    status: 200
    data: Authenticated
    meta: AuthenticationMeta
}

/** 200 OK - Configuration */
export interface ConfigurationResponse extends AllauthResponse<AllauthConfiguration> {
    status: 200
    data: AllauthConfiguration
}

/** 200 OK - Email list */
export interface EmailListResponse extends AllauthResponse<EmailAddress[]> {
    status: 200
    data: EmailAddress[]
}

/** 200 OK - Session list */
export interface SessionListResponse extends AllauthResponse<Session[]> {
    status: 200
    data: Session[]
}

/** 200 OK - Authenticator list */
export interface AuthenticatorListResponse extends AllauthResponse<Authenticator[]> {
    status: 200
    data: Authenticator[]
}

/** 200 OK - Provider account list */
export interface ProviderAccountListResponse extends AllauthResponse<ProviderAccount[]> {
    status: 200
    data: ProviderAccount[]
}

/** 200 OK - TOTP status */
export interface TOTPStatusResponse extends AllauthResponse<TOTPStatus> {
    status: 200
    data: TOTPStatus
}

/** 200 OK - Recovery codes */
export interface RecoveryCodesResponse extends AllauthResponse<SensitiveRecoveryCodesAuthenticator> {
    status: 200
    data: SensitiveRecoveryCodesAuthenticator
}

/** 200 OK - WebAuthn creation options */
export interface WebAuthnCreationOptionsResponse extends AllauthResponse<WebAuthnCreationOptions> {
    status: 200
    data: WebAuthnCreationOptions
}

/** 200 OK - WebAuthn request options */
export interface WebAuthnRequestOptionsResponse extends AllauthResponse<WebAuthnRequestOptions> {
    status: 200
    data: WebAuthnRequestOptions
}

/** 200 OK - Email verification info */
export interface EmailVerificationInfoResponse extends AllauthResponse<{ email: Email; user: User }> {
    status: 200
    data: { email: Email; user: User }
}

/** 401 - Authentication required (not authenticated) */
export interface AuthenticationRequiredResponse extends AllauthResponse<{ flows: Flow[] }, AuthenticationMeta> {
    status: 401
    data: { flows: Flow[] }
    meta: AuthenticationMeta & { is_authenticated: false }
}

/** 401 - Reauthentication required (authenticated but needs reauthentication) */
export interface ReauthenticationRequiredResponse extends AllauthResponse<ReauthenticationRequired, AuthenticatedMeta> {
    status: 401
    data: ReauthenticationRequired
    meta: AuthenticatedMeta
}

/** 400 - Bad request / validation error */
export interface ErrorResponse extends AllauthResponse<never> {
    status: 400
    errors: AuthError[]
}

/** 403 - Forbidden */
export interface ForbiddenResponse extends AllauthResponse<never> {
    status: 403
}

/** 409 - Conflict */
export interface ConflictResponse extends AllauthResponse<never> {
    status: 409
}

/** 410 - Session gone/expired */
export interface SessionGoneResponse extends AllauthResponse<Record<string, never>, AuthenticationMeta> {
    status: 410
    data: Record<string, never>
    meta: AuthenticationMeta
}

// =============================================================================
// API Request Types
// =============================================================================

export interface LoginRequest {
    email?: Email
    username?: Username
    phone?: Phone
    password: Password
}

export interface SignupRequest {
    email: Email
    password: Password
    [key: string]: unknown // Additional custom signup fields
}

export interface ProviderSignupRequest {
    email: Email
    [key: string]: unknown
}

export interface ReauthenticateRequest {
    password: Password
}

export interface RequestLoginCodeRequest {
    email?: Email
    phone?: Phone
}

export interface ConfirmLoginCodeRequest {
    code: Code
}

export interface MFAAuthenticateRequest {
    code: AuthenticatorCode
}

export interface MFATrustRequest {
    trust: boolean
}

export interface RequestPasswordResetRequest {
    email: Email
}

export interface ResetPasswordRequest {
    key: string
    password: Password
}

export interface VerifyEmailRequest {
    key: string
}

export interface ChangePasswordRequest {
    current_password?: Password
    new_password: Password
}

export interface AddEmailRequest {
    email: Email
}

export interface ProviderRedirectRequest {
    provider: ProviderID
    process: OAuthProcess
    callback_url: string
}

export interface ProviderTokenRequest {
    provider: ProviderID
    process: OAuthProcess
    token: {
        client_id: ClientID
        id_token?: string
        access_token?: string
    }
}

export interface WebAuthnAddRequest {
    name: string
    credential: unknown // WebAuthn RegistrationResponseJSON
}

export interface WebAuthnAuthenticateRequest {
    credential: unknown // WebAuthn AuthenticationResponseJSON
}

export interface WebAuthnUpdateRequest {
    id: AuthenticatorID
    name?: string
}

export interface WebAuthnDeleteRequest {
    authenticators: AuthenticatorID[]
}

export interface EndSessionsRequest {
    sessions: number[]
}

// =============================================================================
// Union Types for Responses
// =============================================================================

/** Possible responses from authentication endpoints */
export type AuthResponse =
    | AuthenticatedResponse
    | AuthenticationRequiredResponse
    | ReauthenticationRequiredResponse
    | ErrorResponse

/** Possible responses from session status endpoint */
export type SessionStatusResponse =
    | AuthenticatedResponse
    | AuthenticationRequiredResponse
    | SessionGoneResponse
