<?php

namespace App\Http\Middleware;

use App\Models\ProbeLocation;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

/**
 * Authenticates incoming check-result pushes from probe nodes. Each probe
 * has a `secret_hash` (bcrypt) stored in DB. The probe sends:
 *
 *   X-Probe-Code: noc-primary
 *   X-Probe-Secret: noc_probe_xxxxxxxxxxxx
 *
 * On match we attach the ProbeLocation to the request as `probe_location`
 * so the controller can avoid re-querying.
 *
 * Mirrors AuthenticateAgent — same security model (header-based,
 * hashed secret, attribute injection).
 */
class AuthenticateProbe
{
    public function handle(Request $request, Closure $next)
    {
        $code = $request->header('X-Probe-Code');
        $secret = $request->header('X-Probe-Secret');

        if (!$code || !$secret) {
            return response()->json(['error' => 'missing_credentials'], 401);
        }

        $location = ProbeLocation::where('code', $code)->first();
        if (!$location || !$location->secret_hash) {
            return response()->json(['error' => 'unknown_probe'], 401);
        }

        if (!Hash::check($secret, $location->secret_hash)) {
            return response()->json(['error' => 'invalid_secret'], 401);
        }

        if ($location->status === 'decommissioned') {
            return response()->json(['error' => 'probe_decommissioned'], 403);
        }

        // Update last-seen + IP on every authenticated push. Cheap update,
        // and gives us heartbeat data for the dashboard.
        $location->forceFill([
            'last_seen_at' => now(),
            'public_ip' => $request->ip(),
        ])->save();

        $request->attributes->set('probe_location', $location);

        return $next($request);
    }
}
