<?php

namespace App\Http\Middleware;

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

class BackofficeAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        // 1. VERIFICAR IP WHITELIST (solo si está habilitado)
        // Se deshabilita para ingreso de Asesores
        // if (config('backoffice.security.enable_ip_whitelist', false)) {
        //     $clientIp = $this->getClientIp($request);
        //     $authorizedIps = config('backoffice.authorized_ips', []);
            
        //     if (!$this->isIpAuthorized($clientIp, $authorizedIps)) {
        //         Log::warning('Unauthorized IP access attempt', [
        //             'ip' => $clientIp,
        //             'user_agent' => $request->userAgent(),
        //             'url' => $request->fullUrl(),
        //         ]);

        //         return response()->view('errors.403', [
        //             'message' => 'Acceso denegado. Tu IP no está autorizada para acceder al backoffice.',
        //             'ip' => $clientIp,
        //         ], 403);
        //     }
        // }

        // 2. VERIFICAR AUTENTICACIÓN
        if (!session('backoffice_authenticated')) {
            // Si es una petición AJAX, devolver JSON
            if ($request->expectsJson()) {
                return response()->json([
                    'error' => 'No autenticado',
                    'message' => 'Sesión expirada o no válida'
                ], 401);
            }
            
            // Redirigir al login
            return redirect()->route('login')->with('error', 'Debes iniciar sesión para acceder.');
        }

        // 3. VERIFICAR EXPIRACIÓN DE SESIÓN
        if (config('backoffice.security.enable_session_timeout', true)) {
            $lastActivity = session('backoffice_last_activity');
            $sessionLifetime = config('backoffice.session.lifetime', 120) * 60; // convertir a segundos

            if ($lastActivity && (time() - $lastActivity) > $sessionLifetime) {
                // Limpiar sesión expirada
                session()->forget('backoffice_authenticated');
                session()->forget('backoffice_user');
                session()->forget('backoffice_login_time');
                session()->forget('backoffice_last_activity');
                session()->forget('api_token');
                session()->forget('user_data');

                Log::warning('Session expired for user', [
                    'username' => session('backoffice_user', 'unknown'),
                    'last_activity' => date('Y-m-d H:i:s', $lastActivity),
                    'inactivity_minutes' => round((time() - $lastActivity) / 60, 2),
                ]);

                if ($request->expectsJson()) {
                    return response()->json([
                        'error' => 'Sesión expirada',
                        'message' => 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.'
                    ], 401);
                }

                return redirect()->route('login')->with('error', 'Tu sesión ha expirado. Por favor, inicia sesión nuevamente.');
            }

            // Actualizar última actividad
            session(['backoffice_last_activity' => time()]);
        }

        return $next($request);
    }

    /**
     * Obtener IP real del cliente
     */
    private function getClientIp(Request $request): string
    {
        return $request->header('CF-Connecting-IP') 
            ?? $request->header('X-Real-IP')
            ?? $request->header('X-Forwarded-For')
            ?? $request->ip();
    }

    /**
     * Verificar si la IP está autorizada
     */
    private function isIpAuthorized(string $clientIp, array $authorizedIps): bool
    {
        foreach ($authorizedIps as $authorizedIp) {
            if ($clientIp === $authorizedIp) {
                return true;
            }
            
            // Soporte CIDR básico
            if (strpos($authorizedIp, '/') !== false && $this->ipInCidr($clientIp, $authorizedIp)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Verificar si IP está en rango CIDR
     */
    private function ipInCidr(string $ip, string $cidr): bool
    {
        list($subnet, $mask) = explode('/', $cidr);
        
        if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || 
            !filter_var($subnet, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            return false;
        }
        
        return (ip2long($ip) & (-1 << (32 - (int)$mask))) === (ip2long($subnet) & (-1 << (32 - (int)$mask)));
    }
}