<?php

namespace App\Http\Middleware;

use App\Helpers\ProfileAuthorizationHelper;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

/**
 * Require Admin Profile Middleware
 *
 * Ensures that only administrators or central banks can access admin routes.
 * Prevents IDOR attacks and cross-guard access by validating profile ownership
 * using ProfileAuthorizationHelper.
 *
 * Usage:
 * - Apply to routes that require admin or central bank access
 * - Validates active profile from session
 * - Checks cross-guard attacks via ProfileAuthorizationHelper
 * - Logs all access attempts for security monitoring
 */
class RequireAdminProfile
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        // Get active profile from session
        $activeProfileType = session('activeProfileType');
        $activeProfileId = session('activeProfileId');

        if (!$activeProfileType || !$activeProfileId) {
            Log::warning('RequireAdminProfile: No active profile in session', [
                'ip_address' => $request->ip(),
                'url' => $request->fullUrl(),
            ]);
            abort(403, __('No active profile selected'));
        }

        $profile = $activeProfileType::find($activeProfileId);

        if (!$profile) {
            Log::warning('RequireAdminProfile: Active profile not found', [
                'active_profile_type' => $activeProfileType,
                'active_profile_id' => $activeProfileId,
                'ip_address' => $request->ip(),
                'url' => $request->fullUrl(),
            ]);
            abort(403, __('Active profile not found'));
        }

        // Validate profile ownership using ProfileAuthorizationHelper
        // This prevents cross-guard attacks (e.g., web user accessing admin profile)
        ProfileAuthorizationHelper::authorize($profile);

        // Verify admin or central bank permissions
        if ($profile instanceof \App\Models\Admin) {
            // Admin access OK
            Log::info('RequireAdminProfile: Admin access granted', [
                'admin_id' => $profile->id,
                'admin_name' => $profile->name,
                'ip_address' => $request->ip(),
                'url' => $request->fullUrl(),
            ]);

            return $next($request);
        }

        if ($profile instanceof \App\Models\Bank) {
            // Only central bank (level 0) can access admin routes
            if ($profile->level === 0) {
                Log::info('RequireAdminProfile: Central bank access granted', [
                    'bank_id' => $profile->id,
                    'bank_name' => $profile->name,
                    'bank_level' => $profile->level,
                    'ip_address' => $request->ip(),
                    'url' => $request->fullUrl(),
                ]);

                return $next($request);
            }

            Log::warning('RequireAdminProfile: Non-central bank attempted admin access', [
                'bank_id' => $profile->id,
                'bank_name' => $profile->name,
                'bank_level' => $profile->level,
                'ip_address' => $request->ip(),
                'url' => $request->fullUrl(),
            ]);

            abort(403, __('Central bank access required for admin functions'));
        }

        // Not admin or central bank
        Log::warning('RequireAdminProfile: Unauthorized profile type attempted admin access', [
            'profile_type' => get_class($profile),
            'profile_id' => $profile->id,
            'ip_address' => $request->ip(),
            'url' => $request->fullUrl(),
        ]);

        abort(403, __('Admin or central bank access required'));
    }
}
