<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
 * Incidencias del límite de peticiones de la API.
 *
 * NO es una tabla de peticiones: `api_request_logs` ya lo es, y precisamente por
 * crecer sin freno dejó el visor inusable. Aquí va **una fila por IP, ventana y tipo
 * de límite**, con el máximo observado. Una IP que se pase mil veces en un minuto
 * genera una fila, no mil.
 *
 * Sirve para responder lo que antes no se podía: qué IPs están cerca del tope,
 * cuáles lo han cruzado, desde cuándo y con qué acción. Y se conserva aunque se
 * purgue `api_request_logs`, que es cuando más falta hace.
 *
 * Ver known-issues MGR-008.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('api_rate_events', function (Blueprint $table) {
            $table->id();

            $table->string('ip', 45);

            // Inicio de la ventana del contador: agrupa las observaciones para que no
            // haya una fila por petición.
            $table->dateTime('window_started_at');

            // `failures` (401/403) o `requests` (techo total).
            $table->string('limit_kind', 20);

            // `warning` al cruzar el margen de aviso, `blocked` al cortar de verdad.
            $table->string('kind', 20);

            // Máximo observado en la ventana y el tope que se aplicaba.
            $table->unsignedInteger('observed')->default(0);
            $table->unsignedInteger('limit_value')->default(0);

            // Cuántas peticiones se han rechazado ya en esta ventana.
            $table->unsignedInteger('rejected')->default(0);

            // Contexto de la última petición vista, para saber a quién avisar.
            $table->string('host')->nullable();
            $table->string('action', 50)->nullable();
            $table->string('plugin', 100)->nullable();
            $table->string('user_agent')->nullable();

            $table->timestamps();

            $table->unique(['ip', 'window_started_at', 'limit_kind'], 'api_rate_events_window_unique');
            $table->index('ip');
            $table->index('window_started_at');
            $table->index(['kind', 'window_started_at']);
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('api_rate_events');
    }
};
