<?php

namespace SiipAvailableIps;

/**
 * Helper class para manejar rangos de IPs administrativas personalizados por segmento
 */
class AdminRangeHelper
{
    /**
     * Obtiene los límites de IPs administrativas para un segmento específico
     * 
     * @param string|int $segmentNumber Número del segmento (ej: 18 para 172.16.18.x)
     * @param string $jsonData JSON con configuración de rangos
     * @return array|null Array con límites o null si el segmento no existe
     */
    public static function getSegmentLimits($segmentNumber, $jsonData)
    {
        if (empty($jsonData)) {
            return null;
        }
        
        $data = json_decode($jsonData, true);
        
        if (!isset($data['segmentos']) || !is_array($data['segmentos'])) {
            return null;
        }
        
        foreach ($data['segmentos'] as $segmento) {
            if ($segmento['segmento'] == $segmentNumber) {
                // Última IP del bloque inicial
                $ultimoInicial = 0;
                if (isset($segmento['administrativas_iniciales']) && is_array($segmento['administrativas_iniciales'])) {
                    foreach ($segmento['administrativas_iniciales'] as $rango) {
                        if (isset($rango['hasta']) && $rango['hasta'] > $ultimoInicial) {
                            $ultimoInicial = $rango['hasta'];
                        }
                    }
                }
                
                // Primera IP del bloque final
                $primerFinal = 999;
                if (isset($segmento['administrativas_finales']) && is_array($segmento['administrativas_finales'])) {
                    foreach ($segmento['administrativas_finales'] as $rango) {
                        if (isset($rango['inicio']) && $rango['inicio'] < $primerFinal) {
                            $primerFinal = $rango['inicio'];
                        }
                    }
                }
                
                return [
                    'ultimo_inicial_reservado' => $ultimoInicial,
                    'primer_final_reservado' => $primerFinal,
                    'rangos_iniciales' => $segmento['administrativas_iniciales'] ?? [],
                    'rangos_finales' => $segmento['administrativas_finales'] ?? []
                ];
            }
        }
        
        return null;
    }
    
    /**
     * Verifica si una IP es administrativa según configuración JSON personalizada
     * 
     * @param string $ip Dirección IP completa (ej: 172.16.18.45)
     * @param string $jsonData JSON con configuración de rangos
     * @return bool True si es IP administrativa
     */
    public static function isAdminIpCustom($ip, $jsonData)
    {
        $parts = explode('.', $ip);
        if (count($parts) !== 4) {
            return false;
        }
        
        $segment = $parts[2];
        $lastOctet = (int)$parts[3];
        
        $limits = self::getSegmentLimits($segment, $jsonData);
        if (!$limits) {
            return false;
        }
        
        // Verificar rangos iniciales
        if (isset($limits['rangos_iniciales']) && is_array($limits['rangos_iniciales'])) {
            foreach ($limits['rangos_iniciales'] as $rango) {
                if ($lastOctet >= $rango['inicio'] && $lastOctet <= $rango['hasta']) {
                    return true;
                }
            }
        }
        
        // Verificar rangos finales
        if (isset($limits['rangos_finales']) && is_array($limits['rangos_finales'])) {
            foreach ($limits['rangos_finales'] as $rango) {
                if ($lastOctet >= $rango['inicio'] && $lastOctet <= $rango['hasta']) {
                    return true;
                }
            }
        }
        
        return false;
    }
    
    /**
     * Valida el formato del JSON de configuración
     * 
     * @param string $jsonData JSON a validar
     * @return array Array con 'valid' (bool) y 'error' (string|null)
     */
    public static function validateConfigJson($jsonData)
    {
        if (empty($jsonData)) {
            return ['valid' => false, 'error' => 'JSON vacío'];
        }
        
        $data = json_decode($jsonData, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            return ['valid' => false, 'error' => 'JSON inválido: ' . json_last_error_msg()];
        }
        
        if (!isset($data['segmentos']) || !is_array($data['segmentos'])) {
            return ['valid' => false, 'error' => 'Falta el array "segmentos"'];
        }
        
        return ['valid' => true, 'error' => null];
    }
}
