<?php
// /lib/DataSources.php - ФИНАЛЬНАЯ ВЕРСИЯ БЕЗ PIZZA
require_once 'RealDataSources.php';

class DataSources {
    private static $ranges = [
        'oil'         => [1, 50],
        'media'       => [500, 10000],
        'navy'        => [1, 5],
        'vip'         => [5, 20],
        'gov'         => [1, 4],
        'gold'        => [1, 20],
        'cyber'       => [1, 5],
        'energy'      => [1, 5],
        'social'      => [1, 5],
        'mfa'         => [1, 5],
        'pm'          => [1, 5],
        'contractors' => [1, 5],
        'darknet'     => [1, 5],
        'medical'     => [1, 5],
        'satellite'   => [1, 5],
        'evacuation'  => [1, 5],
        'reserves'    => [1, 5],
        // pizza УДАЛЁН
    ];

    // НОРМАЛИЗОВАННЫЕ ВЕСА (сумма = 1.0)
    private static $weights = [
        'oil'         => 0.284,  // 28.4%
        'media'       => 0.227,  // 22.7%
        'navy'        => 0.171,  // 17.1%
        'vip'         => 0.136,  // 13.6%
        'gov'         => 0.091,  // 9.1%
        'gold'        => 0.081,  // 8.1%
        'cyber'       => 0.070,  // 7.0%
        'energy'      => 0.068,  // 6.8%
        'social'      => 0.057,  // 5.7%
        'mfa'         => 0.023,  // 2.3%
        'pm'          => 0.019,  // 1.9%
        'contractors' => 0.015,  // 1.5%
        'darknet'     => 0.013,  // 1.3%
        'medical'     => 0.010,  // 1.0%
        'satellite'   => 0.009,  // 0.9%
        'evacuation'  => 0.008,  // 0.8%
        'reserves'    => 0.006   // 0.6%
        // pizza УДАЛЁН
    ];

    public static function normalize(string $factor, float $raw_value): float {
        if (!isset(self::$ranges[$factor])) {
            error_log("Фактор '$factor' не найден в ranges");
            return 0;
        }
        
        [$min, $max] = self::$ranges[$factor];
        
        if ($max <= $min) {
            error_log("Некорректный диапазон для '$factor': min=$min, max=$max");
            return 0;
        }
        
        $clamped = max($min, min($max, $raw_value));
        return round((($clamped - $min) / ($max - $min)) * 10, 2);
    }

    public static function calculateIndex(array $scores): array {
        $index = 0.0;
        foreach ($scores as $factor => $score) {
            if (isset(self::$weights[$factor])) {
                $index += $score * self::$weights[$factor];
            }
        }
        $index = round($index, 2);

        $aal = match(true) {
            $index >= 8.0 => 1,
            $index >= 6.5 => 2,
            $index >= 5.0 => 3,
            $index >= 3.5 => 4,
            default => 5
        };

        return ['index' => $index, 'aal' => $aal];
    }

    public static function getValue(string $factor_name) {
        $cacheDir = __DIR__ . '/../cache';
        if (!is_dir($cacheDir)) mkdir($cacheDir, 0755, true);
        $cacheFile = $cacheDir . '/' . $factor_name . '.json';
        $cacheTTL = 900; // 15 минут

        if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $cacheTTL) {
            $cached = json_decode(file_get_contents($cacheFile), true);
            if ($cached && isset($cached['value'])) {
                return $cached['value'];
            }
        }

        $value = null;
        try {
            switch ($factor_name) {
                case 'oil':
                    $value = RealDataSources::getOilVolatility();
                    break;
                case 'media':
                    $value = RealDataSources::getMediaMentions();
                    break;
                case 'navy':
                    $value = RealDataSources::getNavyGroups();
                    break;
                case 'vip':
                    $value = RealDataSources::getDiplomaticFlights();
                    break;
                case 'gov':
                    $value = RealDataSources::getGovActivity();
                    break;
                case 'gold':
                    $value = RealDataSources::getGoldVolatility();
                    break;
                case 'cyber':
                    $value = RealDataSources::getCyberThreats();
                    break;
                case 'energy':
                    $value = RealDataSources::getEnergyVolatility();
                    break;
                case 'social':
                    $value = RealDataSources::getSocialActivity();
                    break;
                case 'mfa':
                case 'pm':
                case 'contractors':
                case 'darknet':
                case 'medical':
                case 'satellite':
                case 'evacuation':
                case 'reserves':
                    $value = rand(1, 3); // временные заглушки
                    break;
                default:
                    $value = rand(1, 3);
            }
        } catch (Exception $e) {
            error_log("Ошибка получения данных для $factor_name: " . $e->getMessage());
            $value = rand(1, 3);
        }

        if ($value === null) {
            $value = rand(1, 3);
        }

        file_put_contents($cacheFile, json_encode([
            'value' => $value, 
            'timestamp' => time(),
            'factor' => $factor_name
        ]));

        return $value;
    }

    public static function calculateMetrics(float $index): array {
        return [
            'time_to_aa3' => round(max(0.5, min(7.0, 7.0 - $index)), 2),
            'signal_detection_time' => round(max(6, min(72, 72 - ($index * 8))), 0),
            'detection_to_action_time' => round(max(1, min(24, 24 - ($index * 3))), 0),
        ];
    }

    public static function getAllData(): array {
        $factors = array_keys(self::$weights);
        $result = [];
        foreach ($factors as $factor) {
            $result[$factor] = self::getValue($factor);
        }
        return $result;
    }

    public static function getDebugInfo(): array {
        $factors = array_keys(self::$weights);
        $raw_values = [];
        $scores = [];
        foreach ($factors as $factor) {
            $raw = self::getValue($factor);
            $score = self::normalize($factor, $raw);
            $raw_values[$factor] = $raw;
            $scores[$factor] = $score;
        }
        $result = self::calculateIndex($scores);
        return [
            'factors' => $factors,
            'raw_values' => $raw_values,
            'scores' => $scores,
            'weights' => self::$weights,
            'result' => $result,
            'total_weight' => array_sum(self::$weights)
        ];
    }
}
?>