<?php
// lib/DataSources.php — ФИНАЛЬНАЯ ВЕРСИЯ: РЕАЛЬНЫЕ ДАННЫЕ + FALLBACK
require_once __DIR__ . '/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],    // K твитов
        'mfa'         => [1, 5],    // твитов
        'pm'          => [1, 5],    // твитов
        'contractors' => [1, 5],    // контрактов
        'darknet'     => [1, 5],    // результатов
        'medical'     => [1, 5],    // упоминаний
        'satellite'   => [1, 5],    // изображений
        'evacuation'  => [1, 5],    // сигналов
        'reserves'    => [1, 5]     // упоминаний
    ];

    private static $weights = [
        'oil'         => 0.220,
        'media'       => 0.176,
        'navy'        => 0.133,
        'vip'         => 0.105,
        'gov'         => 0.071,
        'gold'        => 0.063,
        'cyber'       => 0.054,
        'energy'      => 0.053,
        'social'      => 0.044,
        'mfa'         => 0.018,
        'pm'          => 0.015,
        'contractors' => 0.012,
        'darknet'     => 0.010,
        'medical'     => 0.008,
        'satellite'   => 0.007,
        'evacuation'  => 0.006,
        'reserves'    => 0.005
    ];

    // Fallback: реальные данные на 26.10.2025 (из поиска)
    private static $fallbackValues = [
        'oil'         => 12.5,   // WTI волатильность
        'media'       => 1520,   // Google News
        'navy'        => 3,      // Nimitz, Vinson, Ford
        'vip'         => 14,     // EL AL + evac
        'gov'         => 3,      // White House
        'gold'        => 15.2,   // Kitco
        'cyber'       => 4,      // OTX
        'energy'      => 3.36,   // Henry Hub
        'social'      => 3.8,    // X (3800+)
        'mfa'         => 2,      // @IsraelMFA
        'pm'          => 1,      // @IsraeliPM
        'contractors' => 3,      // DoD
        'darknet'     => 3,      // DarkOwl
        'medical'     => 2,      // WHO
        'satellite'   => 4,      // Maxar
        'evacuation'  => 3,      // State Dept
        'reserves'    => 4       // IDF
    ];

    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) 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 => 5,
            $index >= 6.5 => 4,
            $index >= 5.0 => 3,
            $index >= 3.5 => 2,
            default => 1
        };

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

    public static function getValue(string $factor_name): float {
        $cacheDir = __DIR__ . '/../cache';
        if (!is_dir($cacheDir)) mkdir($cacheDir, 0755, true);
        $cacheFile = $cacheDir . '/' . $factor_name . '.json';

        $cacheTimes = require __DIR__ . '/RealDataSources.php';
        $cacheTTL = $cacheTimes[$factor_name] ?? 3600;

        // 1. Проверяем кэш
        if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $cacheTTL) {
            $cached = json_decode(file_get_contents($cacheFile), true);
            if ($cached && isset($cached['value']) && $cached['value'] > 0) {
                return (float)$cached['value'];
            }
        }

        // 2. Пытаемся получить реальное значение
        $value = match ($factor_name) {
            'oil'         => RealDataSources::getOilVolatility(),
            'media'       => RealDataSources::getMediaMentions(),
            'navy'        => RealDataSources::getNavyGroups(),
            'vip'         => RealDataSources::getDiplomaticFlights(),
            'gov'         => RealDataSources::getGovActivity(),
            'gold'        => RealDataSources::getGoldVolatility(),
            'cyber'       => RealDataSources::getCyberThreats(),
            'energy'      => RealDataSources::getEnergyVolatility(),
            'social'      => RealDataSources::getSocialActivity(),
            'mfa'         => RealDataSources::getMfaActivity(),
            'pm'          => RealDataSources::getPmActivity(),
            'contractors' => RealDataSources::getContractorsActivity(),
            'darknet'     => RealDataSources::getDarknetActivity(),
            'medical'     => RealDataSources::getMedicalReserves(),
            'satellite'   => RealDataSources::getSatelliteActivity(),
            'evacuation'  => RealDataSources::getEvacuationSignals(),
            'reserves'    => RealDataSources::getReservesMobilization(),
            default       => 0
        };

        // 3. Если 0 или null — используем fallback
        if ($value <= 0 || $value === null) {
            $value = self::$fallbackValues[$factor_name] ?? 0;
            error_log("FALLBACK для $factor_name: $value (реальные данные)");
        }

        // 4. Сохраняем в кэш
        file_put_contents($cacheFile, json_encode([
            'value' => $value,
            'timestamp' => time(),
            'factor' => $factor_name,
            'source' => ($value === self::$fallbackValues[$factor_name] ?? null) ? 'fallback' : 'live'
        ]));

        return (float)$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;
    }

    // Дебаг: показывает raw, score, weight, fallback
    public static function getDebugInfo(): array {
        $factors = array_keys(self::$weights);
        $raw_values = [];
        $scores = [];
        $sources = [];
        foreach ($factors as $factor) {
            $raw = self::getValue($factor);
            $score = self::normalize($factor, $raw);
            $raw_values[$factor] = $raw;
            $scores[$factor] = $score;
            $cacheFile = __DIR__ . '/../cache/' . $factor . '.json';
            $source = 'unknown';
            if (file_exists($cacheFile)) {
                $cached = json_decode(file_get_contents($cacheFile), true);
                $source = $cached['source'] ?? 'unknown';
            }
            $sources[$factor] = $source;
        }
        $result = self::calculateIndex($scores);
        return [
            'factors' => $factors,
            'raw_values' => $raw_values,
            'scores' => $scores,
            'weights' => self::$weights,
            'sources' => $sources,
            'result' => $result,
            'total_weight' => array_sum(self::$weights),
            'fallback_used' => array_filter($sources, fn($s) => $s === 'fallback')
        ];
    }
}