import { get, post } from '@/lib/http/client'
import type {
  ActionMessageResponse,
  AuthCapabilities,
  BootstrapAdminRequest,
  ForgotPasswordRequest,
  LoginByEmailCodeRequest,
  LoginByPasswordRequest,
  LoginBySmsCodeRequest,
  OAuthAuthorizationResponse,
  RegisterRequest,
  RegisterResponse,
  ResendActivationEmailRequest,
  ResetPasswordRequest,
  SessionUser,
  SendEmailCodeRequest,
  SendSmsCodeRequest,
  TokenBundle,
  ValidateResetTokenResponse,
} from '@/types'

function normalizeAuthCapabilities(capabilities?: Partial<AuthCapabilities> | null): AuthCapabilities {
  return {
    password: capabilities?.password ?? true,
    email_activation: capabilities?.email_activation ?? false,
    email_code: capabilities?.email_code ?? false,
    sms_code: capabilities?.sms_code ?? false,
    password_reset: capabilities?.password_reset ?? false,
    admin_bootstrap_required: capabilities?.admin_bootstrap_required ?? false,
    oauth_providers: Array.isArray(capabilities?.oauth_providers) ? capabilities.oauth_providers : [],
  }
}

export async function getAuthCapabilities(): Promise<AuthCapabilities> {
  const capabilities = await get<Partial<AuthCapabilities>>('/auth/capabilities', undefined, { auth: false })
  return normalizeAuthCapabilities(capabilities)
}

export function loginByPassword(data: LoginByPasswordRequest): Promise<TokenBundle> {
  return post<TokenBundle>('/auth/login', data, { auth: false, credentials: 'include' })
}

export function loginByEmailCode(data: LoginByEmailCodeRequest): Promise<TokenBundle> {
  return post<TokenBundle>('/auth/login/email-code', data, { auth: false, credentials: 'include' })
}

export function loginBySmsCode(data: LoginBySmsCodeRequest): Promise<TokenBundle> {
  return post<TokenBundle>('/auth/login/code', data, { auth: false, credentials: 'include' })
}

export function register(data: RegisterRequest): Promise<RegisterResponse> {
  return post<RegisterResponse>('/auth/register', data, { auth: false })
}

export function bootstrapAdmin(data: BootstrapAdminRequest): Promise<TokenBundle> {
  return post<TokenBundle>('/auth/bootstrap-admin', data, { auth: false, credentials: 'include' })
}

export function activateEmail(token: string): Promise<ActionMessageResponse> {
  return get<ActionMessageResponse>('/auth/activate', { token }, { auth: false })
}

export function resendActivationEmail(
  data: ResendActivationEmailRequest,
): Promise<ActionMessageResponse> {
  return post<ActionMessageResponse>('/auth/resend-activation', data, { auth: false })
}

export function sendEmailCode(data: SendEmailCodeRequest): Promise<void> {
  return post<void>('/auth/send-email-code', data, { auth: false })
}

export function sendSmsCode(data: SendSmsCodeRequest): Promise<void> {
  return post<void>('/auth/send-code', data, { auth: false })
}

export function refreshSession(refreshToken?: string | null): Promise<TokenBundle> {
  const body = refreshToken ? { refresh_token: refreshToken } : undefined
  return post<TokenBundle>('/auth/refresh', body, { auth: false, credentials: 'include' })
}

export function getOAuthAuthorizationUrl(
  provider: string,
  returnTo: string,
): Promise<OAuthAuthorizationResponse> {
  return get<OAuthAuthorizationResponse>(
    `/auth/oauth/${provider}`,
    { return_to: returnTo },
    { auth: false },
  )
}

export function exchangeOAuthHandoff(code: string): Promise<TokenBundle> {
  return post<TokenBundle>('/auth/oauth/exchange', { code }, { auth: false, credentials: 'include' })
}

export function logout(refreshToken?: string | null): Promise<void> {
  return post<void>('/auth/logout', refreshToken ? { refresh_token: refreshToken } : undefined, {
    credentials: 'include',
  })
}

export function getUserInfo(): Promise<SessionUser> {
  return get<SessionUser>('/auth/userinfo')
}

export function forgotPassword(data: ForgotPasswordRequest): Promise<void> {
  return post<void>('/auth/forgot-password', data, { auth: false })
}

export function validateResetToken(token: string): Promise<ValidateResetTokenResponse> {
  return get<ValidateResetTokenResponse>('/auth/reset-password', { token }, { auth: false })
}

export function resetPassword(data: ResetPasswordRequest): Promise<void> {
  return post<void>('/auth/reset-password', data, { auth: false })
}

export interface TotpStatus {
  totp_enabled: boolean
}

export interface TotpSetup {
  secret: string
  qr_code_base64: string
  recovery_codes: string[]
}

export function getTwoFactorStatus(): Promise<TotpStatus> {
  return get<TotpStatus>('/auth/2fa/status')
}

export function getTwoFactorSetup(): Promise<TotpSetup> {
  return get<TotpSetup>('/auth/2fa/setup')
}

export function enableTwoFactor(code: string): Promise<void> {
  return post<void>('/auth/2fa/enable', { code })
}

export function disableTwoFactor(code: string): Promise<void> {
  return post<void>('/auth/2fa/disable', { code })
}

export function verifyTwoFactor(code: string, deviceId?: string): Promise<void> {
  return post<void>('/auth/2fa/verify', { code, device_id: deviceId })
}
