import type { FastifyInstance, FastifyRequest, FastifyReply } from "fastify"
import { Type } from "@sinclair/typebox"
import { CACHE_CONFIG } from "@m/cache/providers/valkey/valkeyConfig"

const { KEY_PREFIXES } = CACHE_CONFIG

export const getBlockedLogins = (fastify: FastifyInstance) => ({
  schema: {
    summary: "Get all currently blocked login attempts",
    tags: ["admin"],
    response: {
      200: Type.Array(
        Type.Object({
          key: Type.String(),
          ttl: Type.Number(),
          attempts: Type.Number(),
        }),
      ),
    },
  },
  handler: async (_request: FastifyRequest, reply: FastifyReply) => {
    const lockKeys = await fastify.cache.keys(`${KEY_PREFIXES.LOGIN_LOCK}*`)

    const blocks = await Promise.all(
      lockKeys.map(async (key: string) => {
        const clientKey = key.replace(KEY_PREFIXES.LOGIN_LOCK, "")
        const attemptsKey = `${KEY_PREFIXES.LOGIN_ATTEMPTS}${clientKey}`

        const [ttl, attempts] = await Promise.all([
          fastify.cache.ttl(key),
          fastify.cache.get(attemptsKey),
        ])

        return {
          key: clientKey,
          ttl,
          attempts: attempts ? parseInt(attempts) : 0,
        }
      }),
    )

    return reply.send(blocks)
  },
})

export const resetLoginBlock = (fastify: FastifyInstance) => ({
  schema: {
    summary: "Reset login attempts and remove block for specific key",
    tags: ["admin"],
    params: Type.Object({
      key: Type.String(),
    }),
    response: {
      200: Type.Object({
        message: Type.String(),
      }),
    },
  },
  handler: async (
    request: FastifyRequest<{
      Params: { key: string }
    }>,
    reply: FastifyReply,
  ) => {
    const { key } = request.params

    await Promise.all([
      fastify.cache.del(`${KEY_PREFIXES.LOGIN_ATTEMPTS}${key}`),
      fastify.cache.del(`${KEY_PREFIXES.LOGIN_LOCK}${key}`),
    ])

    return reply.send({
      message: `Successfully reset block for ${key}`,
    })
  },
})

export const resetAllLoginBlocks = (fastify: FastifyInstance) => ({
  schema: {
    summary: "Reset all login blocks",
    tags: ["admin"],
    response: {
      200: Type.Object({
        message: Type.String(),
        count: Type.Number(),
      }),
    },
  },
  handler: async (_request: FastifyRequest, reply: FastifyReply) => {
    const lockKeys = await fastify.cache.keys(`${KEY_PREFIXES.LOGIN_LOCK}*`)
    const attemptKeys = await fastify.cache.keys(
      `${KEY_PREFIXES.LOGIN_ATTEMPTS}*`,
    )

    const allKeys = [...lockKeys, ...attemptKeys]
    if (allKeys.length > 0) {
      await fastify.cache.del(...allKeys)
    }

    return reply.send({
      message: "Successfully reset all blocks",
      count: lockKeys.length,
    })
  },
})
