import { createError, getRequestIP } from "h3"
import type { H3Event } from "h3"

const WINDOW_MS = 10 * 60 * 1000
const MAX_ATTEMPTS = 5

interface LoginAttemptState {
  count: number
  windowStartedAt: number
}

const globalStore = globalThis as typeof globalThis & {
  __compAutosLoginAttempts?: Map<string, LoginAttemptState>
}

const attemptsByIp = globalStore.__compAutosLoginAttempts ?? new Map<string, LoginAttemptState>()

globalStore.__compAutosLoginAttempts = attemptsByIp

const getClientKey = (event: H3Event) => getRequestIP(event, { xForwardedFor: true }) || "unknown"

export const assertLoginRateLimit = (event: H3Event) => {
  const key = getClientKey(event)
  const now = Date.now()
  const current = attemptsByIp.get(key)

  if (!current || now - current.windowStartedAt > WINDOW_MS) {
    attemptsByIp.set(key, {
      count: 0,
      windowStartedAt: now
    })
    return
  }

  if (current.count >= MAX_ATTEMPTS) {
    throw createError({
      statusCode: 429,
      statusMessage: "Demasiados intentos. Espera unos minutos antes de volver a probar."
    })
  }
}

export const registerFailedLoginAttempt = (event: H3Event) => {
  const key = getClientKey(event)
  const now = Date.now()
  const current = attemptsByIp.get(key)

  if (!current || now - current.windowStartedAt > WINDOW_MS) {
    attemptsByIp.set(key, {
      count: 1,
      windowStartedAt: now
    })
    return
  }

  attemptsByIp.set(key, {
    count: current.count + 1,
    windowStartedAt: current.windowStartedAt
  })
}

export const clearFailedLoginAttempts = (event: H3Event) => {
  attemptsByIp.delete(getClientKey(event))
}
