<?php
/* reserves.php – Мобилизация резервистов | Avatiah Security Index
   Полная, адаптивная, информативная страница
   Обновление: каждые 30 мин через JS
   Кэш: reserves_cache.json
   API: fetch_reserves.php
   Экспорт: /factors/reserves.json → admin.php
   Дата: 03.11.2025 12:00 UTC
   Статус: AAL 2.0 — ограниченная активность
*/

date_default_timezone_set('UTC');
header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');
header("Content-Security-Policy: default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com;");

// === 1. Чтение кэша ===
$cache_file = __DIR__ . '/reserves_cache.json';
$reserves = [
    'last_update' => date('d.m.Y H:i') . ' UTC',
    'aal' => 2.0,
    'aal_text' => 'Ограниченная активность',
    'aal_color' => '#10b981',
    'media_mentions' => '12-15',
    'official_statements' => '2-3',
    'social_activity' => 'Низкая',
    'chart_data' => [8, 7, 9, 10, 12, 11, 13, 14, 15, 12],
    'factors' => [
        'Плановая ротация резервистов',
        'Частичный донабор спецподразделений',
        'Стабилизация численности',
        'Ограниченные официальные заявления'
    ],
    'sources' => [
        ['name' => 'ЦАХАЛ', 'url' => 'https://www.idf.il'],
        ['name' => 'Ynet', 'url' => 'https://www.ynet.co.il'],
        ['name' => 'Times of Israel', 'url' => 'https://www.timesofisrael.com'],
        ['name' => 'Haaretz', 'url' => 'https://www.haaretz.com']
    ]
];

if (file_exists($cache_file)) {
    $json = file_get_contents($cache_file);
    $tmp = json_decode($json, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        $reserves = array_merge($reserves, $tmp);
    }
}

$aal = $reserves['aal'];
$contribution = round($aal * 1.6, 1); // Вес 8.0% → 1.6 на AAL 5

// === 2. ЭКСПОРТ В /factors/reserves.json (для admin.php) ===
$factors_dir = __DIR__ . '/factors';
if (!is_dir($factors_dir)) mkdir($factors_dir, 0755, true);
file_put_contents(
    $factors_dir . '/reserves.json',
    json_encode([
        'aal' => $aal,
        'last_update' => $reserves['last_update'],
        'contribution' => $contribution,
        'media_mentions' => $reserves['media_mentions'],
        'status' => 'Ограниченная активность'
    ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
);

// === 3. Синхронизация с total_index.json ===
$total_file = __DIR__ . '/total_index.json';
$total = ['factors'=>[], 'total_aal'=>1.0, 'last_update'=>date('d.m.Y H:i').' UTC', 'factor_count'=>0];
if (file_exists($total_file)) {
    $json = file_get_contents($total_file);
    $tmp = json_decode($json, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        $total = $tmp;
    }
}
$total['factors']['reserves'] = ['aal'=>$aal, 'last_update'=>$reserves['last_update'], 'contribution'=>$contribution];
$sum = $cnt = 0;
foreach ($total['factors'] as $f) {
    if (isset($f['aal'])) { $sum += $f['aal']; $cnt++; }
}
$total['total_aal'] = $cnt ? round($sum / $cnt, 2) : 1.0;
$total['factor_count'] = $cnt;
$total['last_update'] = date('d.m.Y H:i').' UTC';
file_put_contents($total_file, json_encode($total, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));

$js_data = json_encode($reserves, JSON_UNESCAPED_UNICODE);
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Мобилизация резервистов | Avatiah Security Index</title>
    <meta name="description" content="AAL <?= $aal ?>. Упоминаний: <?= $reserves['media_mentions'] ?>/день. <?= $reserves['last_update'] ?>">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
    <style>
        :root{--bg:#0a0e1a;--card:#1a2332;--border:#2d3748;--text:#e2e8f0;--accent:#f59e0b;--danger:#ef4444;--warning:#f97316;--success:#10b981;--light:#94a3b8}
        *{margin:0;padding:0;box-sizing:border-box;font-family:'Inter',sans-serif}
        body{background:var(--bg);color:var(--text);line-height:1.6;padding:1rem;min-height:100vh;display:flex;flex-direction:column}
        .container{max-width:1600px;margin:0 auto;display:grid;grid-template-columns:1fr 300px;gap:2rem}
        @media(max-width:992px){.container{grid-template-columns:1fr}.sidebar{position:static}}
        .section{background:var(--card);border-radius:12px;padding:1.5rem;margin-bottom:2rem;border:1px solid var(--border)}
        .header{text-align:center;padding:2rem;background:linear-gradient(135deg,#1e3c72,#2a5298);border-radius:16px;margin-bottom:2rem;color:#fff}
        .header h1{font-size:2.8rem;margin-bottom:.5rem;text-shadow:0 2px 4px rgba(0,0,0,.3)}
        .header .subtitle{color:#cbd5e1;font-size:1.2rem}
        .back-to-index-inline{display:inline-block;margin-top:1rem;background:#2c3e50;color:#fff;padding:.55rem 1.1rem;border-radius:8px;text-decoration:none;font-weight:600;font-size:.9rem;transition:background .2s}
        .back-to-index-inline:hover{background:#34495e}
        .data-warning{background:#f39c12;color:#fff;padding:.5rem;border-radius:8px;margin:1rem 0;text-align:center}
        .level-indicator{text-align:center;margin-bottom:2rem}
        .level-circle{width:120px;height:120px;border-radius:50%;margin:0 auto 1rem;display:flex;align-items:center;justify-content:center;font-size:2.5rem;font-weight:700;color:#fff;box-shadow:0 0 15px rgba(0,0,0,.3)}
        .level-description{font-size:1.2rem;font-weight:500}
        .chart-container{height:300px;margin:1.5rem 0;background:rgba(255,255,255,.05);border-radius:8px;padding:1rem}
        .info-card{background:rgba(255,255,255,.05);border-radius:8px;padding:1rem;margin-top:1rem}
        .warning{border-left:5px solid var(--warning)}
        .impact-scale{display:flex;gap:1rem;margin-top:1rem}
        .scale-item{flex:1;padding:1rem;border-radius:8px;background:rgba(255,255,255,.05);text-align:center}
        .scale-item.active{border:2px solid var(--accent)}
        .scale-value{font-weight:700;margin-bottom:.5rem}
        .scale-description{font-size:.9rem}
        .data-source{background:rgba(255,255,255,.03);border-radius:8px;padding:1rem;margin:.5rem 0;border-left:4px solid #3498db}
        .source-official{border-left-color:var(--success)}
        .source-media{border-left-color:#f39c12}
        .source-estimated{border-left-color:#e74c3c}
        .metric-value{font-size:1.2rem;font-weight:bold;color:#e74c3c}
        .update-status{font-size:.8rem;color:var(--success);text-align:center;margin-top:.5rem}
        .footer{margin-top:auto;background:#111827;padding:2rem;border-top:1px solid var(--border);text-align:center;color:#94a3b8;font-size:.875rem}
    </style>
</head>
<body>
<div class="container">
    <!-- MAIN -->
    <div class="main-content">
        <div class="header">
            <h1>Мобилизация резервистов</h1>
            <p class="subtitle">Вклад в индекс: <?= $contribution ?>%</p>
            <a href="/" class="back-to-index-inline">Назад к индексу</a>
        </div>

        <div class="data-warning">
            <strong>Предупреждение: Внимание:</strong> Реальные данные ограничены. Оценка по открытым источникам.
        </div>

        <div class="section">
            <div class="level-indicator">
                <div class="level-circle" id="aal-circle" style="background:<?= $reserves['aal_color'] ?>"><?= number_format($aal, 1) ?></div>
                <div class="level-description" id="aal-text"><?= $reserves['aal_text'] ?></div>
            </div>
            <p>Уровень мобилизации: <strong><?= number_format($aal, 1) ?> из 5</strong>. Ротация и частичный донабор.</p>
            <div style="margin-top:1rem;text-align:center">
                <div style="display:inline-block;background:<?= $reserves['aal_color'] ?>;color:#fff;padding:.5rem 1rem;border-radius:8px;font-weight:600;font-size:1.1rem">AAL <?= number_format($aal, 1) ?></div>
                <p style="margin:.5rem 0 0;color:#bdc3c7;font-size:.9rem">Низкая угроза</p>
            </div>
        </div>

        <!-- ГРАФИК -->
        <div class="section">
            <h2>Активность упоминаний в СМИ</h2>
            <div class="chart-container">
                <canvas id="reserves-chart"></canvas>
            </div>
        </div>

        <div class="section">
            <h2>Реальные индикаторы</h2>
            <div class="info-card">
                <div class="data-source source-media">
                    <div class="metric-value" id="media-mentions"><?= $reserves['media_mentions'] ?></div>
                    <strong>Упоминаний в СМИ за сутки</strong>
                    <p>Новости о ротации, заявления</p>
                    <small>Источник: Ynet, Times of Israel, Haaretz</small>
                </div>
                <div class="data-source source-official">
                    <div class="metric-value" id="official-statements"><?= $reserves['official_statements'] ?></div>
                    <strong>Официальных заявлений в неделю</strong>
                    <p>Пресс-служба ЦАХАЛ</p>
                    <small>Источник: Пресс-служба ЦАХАЛ</small>
                </div>
                <div class="data-source source-estimated">
                    <div class="metric-value" id="social-activity"><?= $reserves['social_activity'] ?></div>
                    <strong>Активность в соцсетях</strong>
                    <p>Ограниченное обсуждение</p>
                    <small>Источник: Twitter, Facebook</small>
                </div>
            </div>
        </div>

        <div class="section">
            <h2>Текущая ситуация</h2>
            <div class="info-card" id="current-situation">
                <p><strong>Основной этап завершён</strong> — массовый призыв 2023 завершён</p>
                <p><strong>Ротация</strong> — плановая замена</p>
                <p><strong>Донабор</strong> — точечный, спецподразделения</p>
                <p><strong>Стабилизация</strong> — поддержание уровня</p>
                <small>На основе заявлений Минобороны и СМИ</small>
            </div>
        </div>

        <div class="section">
            <h2>Шкала оценки</h2>
            <div class="impact-scale">
                <div class="scale-item <?= $aal<=1.5?'active':'' ?>"><div class="scale-value">1</div><div class="scale-description">Норма<br><small>Ротация</small></div></div>
                <div class="scale-item <?= $aal>1.5&&$aal<=2.5?'active':'' ?>"><div class="scale-value">2</div><div class="scale-description">Внимание<br><small>Частичный донабор</small></div></div>
                <div class="scale-item"><div class="scale-value">3</div><div class="scale-description">Риск<br><small>Локальная</small></div></div>
                <div class="scale-item"><div class="scale-value">4</div><div class="scale-description">Критическая<br><small>Региональная</small></div></div>
                <div class="scale-item"><div class="scale-value">5</div><div class="scale-description">Максимальная<br><small>Полная</small></div></div>
            </div>
        </div>

        <div class="section">
            <h2>Источники</h2>
            <div class="info-card">
                <?php foreach ($reserves['sources'] as $s): ?>
                <p><a href="<?= $s['url'] ?>" target="_blank" style="color:#60a5fa;"><?= $s['name'] ?></a></p>
                <?php endforeach; ?>
            </div>
        </div>
    </div>

    <!-- SIDEBAR -->
    <div class="sidebar">
        <div class="section">
            <h2>Вес в индексе</h2>
            <div class="info-card">
                <div style="text-align:center">
                    <div style="font-size:3rem;font-weight:bold;color:var(--success)"><?= $contribution ?>%</div>
                    <div style="font-size:1.2rem">Высокая значимость</div>
                </div>
            </div>
        </div>

        <div class="section">
            <h2>Пороги AAL</h2>
            <div class="info-card warning">
                <p><strong>AAL 1:</strong> Норма</p>
                <p><strong>AAL 2:</strong> Внимание</p>
                <p><strong>AAL 3:</strong> Риск</p>
                <p><strong>AAL 4:</strong> Критическая</p>
                <p><strong>AAL 5:</strong> Максимальная</p>
            </div>
        </div>

        <div class="section">
            <h2>Метрики</h2>
            <div class="info-card">
                <p><strong>Упоминаний:</strong> <span id="sidebar-media"><?= $reserves['media_mentions'] ?>/день</span></p>
                <p><strong>Заявлений:</strong> <span id="sidebar-official"><?= $reserves['official_statements'] ?>/нед</span></p>
                <p><strong>Соцсети:</strong> <span id="sidebar-social"><?= $reserves['social_activity'] ?></span></p>
                <p><strong>Оценка:</strong> Стабильная</p>
            </div>
        </div>

        <div class="section">
            <h2>Обновление</h2>
            <div class="info-card">
                <p><strong>Последнее:</strong> <span id="last-update-sidebar"><?= date('H:i') ?></span></p>
                <p><strong>Следующее:</strong> <span id="next-update">--:--</span></p>
            </div>
        </div>
    </div>
</div>

<div class="footer">
    <p><strong>Avatiah Security Index</strong> — OSINT в реальном времени</p>
    <p>© 2025 Avatiah • <?= date('d.m.Y H:i') ?></p>
</div>

<!-- ГРАФИК + АВТООБНОВЛЕНИЕ -->
<script>
const initialData = <?= $js_data ?>;
let reservesChart = null;
const UPDATE_INTERVAL = 30;

function initChart(data) {
    const ctx = document.getElementById('reserves-chart').getContext('2d');
    reservesChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: ['-10д','-9д','-8д','-7д','-6д','-5д','-4д','-3д','-2д','сегодня'],
            datasets: [{
                label: 'Упоминания в СМИ',
                data: data.chart_data,
                borderColor: '#10b981',
                backgroundColor: 'rgba(16,185,129,0.1)',
                tension: 0.4,
                fill: true,
                pointRadius: 4
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: { display: false },
                tooltip: { callbacks: { label: ctx => `${ctx.parsed.y} упоминаний` } }
            },
            scales: { y: { beginAtZero: true, max: 20, title: { display: true, text: 'Упоминаний в день' } } }
        }
    });
}

function updateDOM(d) {
    document.querySelectorAll('[id^="aal-"]').forEach(el => {
        if (el.id === 'aal-circle') {
            el.textContent = d.aal.toFixed(1);
            el.style.background = d.aal_color;
        } else if (el.id === 'aal-text') el.textContent = d.aal_text;
    });
    document.getElementById('media-mentions').textContent = d.media_mentions;
    document.getElementById('official-statements').textContent = d.official_statements;
    document.getElementById('social-activity').textContent = d.social_activity;
    document.getElementById('sidebar-media').textContent = d.media_mentions + '/день';
    document.getElementById('sidebar-official').textContent = d.official_statements + '/нед';
    document.getElementById('sidebar-social').textContent = d.social_activity;

    const situation = document.getElementById('current-situation');
    situation.innerHTML = '';
    d.factors.forEach(f => {
        const p = document.createElement('p');
        p.innerHTML = `<strong>${f.split(' — ')[0]}</strong> — ${f.split(' — ')[1] || ''}`;
        situation.appendChild(p);
    });

    if (reservesChart) {
        reservesChart.data.datasets[0].data = d.chart_data;
        reservesChart.update('quiet');
    }

    document.getElementById('update-status').textContent = 'Обновлено!';
    setTimeout(() => document.getElementById('update-status').innerHTML = 'Обновление через <span id="countdown">30:00</span>', 3000);
}

async function fetchData() {
    try {
        await fetch('fetch_reserves.php?' + Date.now());
        const r = await fetch('reserves_cache.json?' + Date.now());
        const d = await r.json();
        updateDOM(d);
    } catch (e) { console.error(e); }
}

function startCountdown() {
    let secs = UPDATE_INTERVAL * 60;
    const interval = setInterval(() => {
        secs--;
        const m = String(Math.floor(secs / 60)).padStart(2, '0');
        const s = String(secs % 60).padStart(2, '0');
        const el = document.getElementById('countdown');
        if (el) el.textContent = `${m}:${s}`;
        document.getElementById('next-update').textContent = new Date(Date.now() + secs * 1000).toTimeString().slice(0,5);
        if (secs <= 0) { clearInterval(interval); fetchData().then(startCountdown); }
    }, 1000);
}

document.addEventListener('DOMContentLoaded', () => {
    initChart(initialData);
    startCountdown();
    setTimeout(fetchData, 30000);
});
</script>
</body>
</html>