<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\PerformanceBudget;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * Performance budgets are SLO-style targets that tell the team "this metric
 * should stay below threshold X for the next Y days". When real measurements
 * exceed the threshold, that's "consumed budget". When 70% of the budget is
 * burned, alert — so we have time to fix before users notice.
 *
 * Example budgets:
 *   - "Apache p95 latency < 500ms over 30 days" — every minute the p95 was
 *     above 500ms counts as a consumed minute. Budget = 1440 minutes (5%
 *     of the month). When you've burned 1008 (70%), warning fires.
 *   - "Mail queue depth < 200 over 24h" — consumed = minutes queue was over.
 *
 * Burn calculation runs in a separate scheduled command (not implemented
 * here; the controller just serves the configured budgets and current burn).
 */
class PerformanceBudgetController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $budgets = PerformanceBudget::orderBy('name')->get()
            ->map(fn ($b) => [
                'id' => $b->id,
                'name' => $b->name,
                'service' => $b->service,
                'target' => $b->target,
                'window' => $b->window,
                'budget' => $b->budget_minutes,
                'consumed' => $b->consumed_minutes ?? 0,
                'unit' => 'minutes',
                'updated_at' => $b->updated_at?->toIso8601String(),
            ]);
        return response()->json(['data' => $budgets]);
    }

    public function store(Request $request): JsonResponse
    {
        abort_unless($request->user()->isAdminOrAbove(), 403);
        $data = $request->validate([
            'name' => 'required|string|max:120',
            'service' => 'required|string|max:60',
            'target' => 'required|string|max:120',
            'window' => 'required|string|in:24h,7d,30d',
            'budget_minutes' => 'required|integer|min:1',
            'metric_query' => 'nullable|string',
        ]);
        $data['consumed_minutes'] = 0;
        $budget = PerformanceBudget::create($data);
        return response()->json(['data' => $budget], 201);
    }

    public function update(Request $request, PerformanceBudget $budget): JsonResponse
    {
        abort_unless($request->user()->isAdminOrAbove(), 403);
        $data = $request->validate([
            'name' => 'sometimes|string|max:120',
            'target' => 'sometimes|string|max:120',
            'window' => 'sometimes|string|in:24h,7d,30d',
            'budget_minutes' => 'sometimes|integer|min:1',
        ]);
        $budget->update($data);
        return response()->json(['data' => $budget]);
    }

    public function destroy(Request $request, PerformanceBudget $budget): JsonResponse
    {
        abort_unless($request->user()->isAdminOrAbove(), 403);
        $budget->delete();
        return response()->json(['ok' => true]);
    }
}
