<?php
/* vip.php – Дипломатические рейсы (Израиль) | Avatiah Security Index
   Обновление: каждые 60 мин через JS
   Кэш: flights_cache.json
   API: fetch_flights.php
   Дата: 02.11.2025 10:00 UTC
   Актуальные данные: Нет активных VIP-рейсов
*/

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'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:;");

$update_interval = 60; // 60 минут

function esc($str) {
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

// --- 1. Чтение кэша ---
$cache_file = __DIR__ . '/flights_cache.json';
$flight_data = [
    'total' => 0,
    'active_flights' => 0,
    'weighted_active' => 0,
    'last_update' => date('d.m.Y H:i') . ' UTC',
    'source' => 'FlightRadar24 + OpenSky Network API + OSINT (Нет активных рейсов на 02.11.2025)',
    'flights' => []
];

if (file_exists($cache_file) && (time() - filemtime($cache_file)) < 1800) {
    $json = file_get_contents($cache_file);
    $tmp = json_decode($json, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        $flight_data = array_merge($flight_data, $tmp);
    }
}

// --- 2. Расчёт AAL ---
$weighted_active = $flight_data['weighted_active'] ?? 0;
$active = $flight_data['active_flights'];
$aal = $weighted_active >= 7 ? 5 : ($weighted_active >= 5 ? 4 : ($weighted_active >= 3.5 ? 3 : ($weighted_active >= 2 ? 2 : 1)));

$aal_levels = [
    1 => ['text' => 'Нормальная', 'color' => '#10b981'],
    2 => ['text' => 'Повышенная', 'color' => '#f59e0b'],
    3 => ['text' => 'Высокая', 'color' => '#f97316'],
    4 => ['text' => 'Критическая', 'color' => '#ef4444'],
    5 => ['text' => 'Экстремальная', 'color' => '#dc2626']
];

// --- 3. Синхронизация с total_index.json ---
$total_index_file = __DIR__ . '/total_index.json';
$total_index = ['factors' => [], 'total_aal' => 1.0, 'last_update' => date('d.m.Y H:i').' UTC', 'factor_count' => 0];

if (file_exists($total_index_file)) {
    $json = file_get_contents($total_index_file);
    $tmp = json_decode($json, true);
    if (json_last_error() === JSON_ERROR_NONE) {
        $total_index = $tmp;
    }
}

$total_index['factors']['vip'] = [
    'aal' => $aal,
    'last_update' => $flight_data['last_update'],
    'active_flights' => $active,
    'weighted_active' => $weighted_active
];

$sum = $count = 0;
foreach ($total_index['factors'] as $f) {
    if (isset($f['aal'])) {
        $sum += $f['aal'];
        $count++;
    }
}
$total_index['total_aal'] = $count > 0 ? round($sum / $count, 2) : 1.0;
$total_index['factor_count'] = $count;
$total_index['last_update'] = date('d.m.Y H:i').' UTC';
file_put_contents($total_index_file, json_encode($total_index, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));

// --- 4. ЭКСПОРТ В /factors/vip.json ---
$factors_dir = __DIR__ . '/factors';
if (!is_dir($factors_dir)) mkdir($factors_dir, 0755, true);

$factor_data = [
    'aal' => $aal,
    'last_update' => $flight_data['last_update'],
    'active_flights' => $active,
    'total_flights' => $flight_data['total'],
    'weighted_active' => $weighted_active,
    'source' => $flight_data['source']
];

file_put_contents(
    "$factors_dir/vip.json",
    json_encode($factor_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
);

// --- 5. JS-данные ---
$js_data = json_encode([
    'aal' => $aal,
    'aal_color' => $aal_levels[$aal]['color'],
    'aal_text' => $aal_levels[$aal]['text'],
    'last_update' => $flight_data['last_update'],
    'active_flights' => $active,
    'total_flights' => $flight_data['total'],
    'weighted_active' => $weighted_active,
    'source' => $flight_data['source'],
    'flights' => $flight_data['flights']
], JSON_UNESCAPED_UNICODE);
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
    <title>VIP-рейсы | Avatiah Security Index</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        :root{--bg:#0a0e1a;--card:#1a2332;--border:#2d3748;--text:#e2e8f0;--green:#10b981;--yellow:#f59e0b;--orange:#f97316;--red:#ef4444;--darkred:#dc2626;--accent:#3498db}
        *{box-sizing:border-box;margin:0;padding:0}
        body{background:var(--bg);color:var(--text);font-family:'Inter',sans-serif;line-height:1.6;padding:clamp(.5rem,2vw,1rem);min-height:100vh;display:flex;flex-direction:column}
        .container{max-width:1600px;margin:auto;display:grid;gap:1.5rem}
        @media(min-width:768px){.container{grid-template-columns:1fr 340px}}
        .section{background:var(--card);border-radius:12px;padding:1.5rem;border:1px solid var(--border)}
        .header{background:linear-gradient(135deg,#1e40af,#1d4ed8);color:#fff;padding:2rem;border-radius:16px;text-align:center}
        .header h1{font-size:clamp(1.8rem,5vw,2.2rem);margin-bottom:.5rem}
        .back-link{display:inline-block;margin-top:1rem;color:#fff;text-decoration:underline;font-size:.9rem}
        .aal-circle{width:120px;height:120px;border-radius:50%;margin:auto;display:flex;align-items:center;justify-content:center;font-size:2.8rem;font-weight:700}
        .aal-info h2{font-size:1.6rem;margin:.5rem 0;text-align:center}
        .aal-stats{display:flex;justify-content:center;gap:1.5rem;font-size:1rem;flex-wrap:wrap}
        .sources,.update-status{font-size:.8rem;color:#94a3b8;text-align:center;margin-top:.5rem}
        .sync-status{color:var(--green)}
        .flight-card{background:rgba(255,255,255,.05);padding:1rem;margin:.75rem 0;border-radius:8px}
        .flight-card h3{display:flex;justify-content:space-between;align-items:center;font-size:1.1rem;margin-bottom:.5rem}
        .callsign-link{color:var(--text);text-decoration:none}
        .callsign-link:hover{text-decoration:underline}
        .status{padding:.2rem .6rem;border-radius:6px;font-size:.75rem;display:flex;align-items:center;gap:.25rem}
        .status-ground{background:#6b7280;color:#fff}
        .status-flight{background:var(--green);color:#fff}
        .status-flight::before{content:'Plane';font-size:1rem}
        .aal-scale{display:flex;gap:0;height:60px;border-radius:8px;overflow:hidden;margin:1rem 0}
        .aal-block{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;font-size:.8rem;color:#fff;position:relative}
        .aal-block:nth-child(1){background:var(--green)}
        .aal-block:nth-child(2){background:var(--yellow)}
        .aal-block:nth-child(3){background:var(--orange)}
        .aal-block:nth-child(4){background:var(--red)}
        .aal-block:nth-child(5){background:var(--darkred)}
        .aal-block.active::after{content:'';position:absolute;bottom:0;left:0;right:0;height:4px;background:#fff}
        .aal-block span{font-size:.7rem;opacity:.9}
        .aal-thresholds{display:flex;flex-direction:column;gap:.4rem;margin-top:.5rem}
        .threshold{display:flex;align-items:center;font-size:.85rem}
        .threshold-bar{width:100%;height:8px;background:#334155;border-radius:4px;overflow:hidden;margin-left:.5rem}
        .threshold-fill{height:100%;transition:width .3s}
        .threshold-1 .threshold-fill{background:var(--green);width:20%}
        .threshold-2 .threshold-fill{background:var(--yellow);width:40%}
        .threshold-3 .threshold-fill{background:var(--orange);width:60%}
        .threshold-4 .threshold-fill{background:var(--red);width:80%}
        .threshold-5 .threshold-fill{background:var(--darkred);width:100%}
        .sidebar .section{margin-bottom:1rem}
        .sidebar h3{font-size:1.1rem;margin-bottom:.5rem}
        .footer{margin-top:auto;background:#111827;padding:1.5rem;border-top:1px solid var(--border);text-align:center;color:#94a3b8;font-size:.85rem}
        .footer a{color:inherit;text-decoration:underline}
        .no-flights{padding:2rem;color:#94a3b8;font-style:italic;text-align:center}
    </style>
</head>
<body>
<div class="container">
    <div class="main-content">
        <!-- HEADER -->
        <div class="header">
            <h1>Дипломатические рейсы (Израиль)</h1>
            <p>AAL = <span id="aal-value"><?= $aal ?></span> | Обновлено: <span id="last-update"><?= esc($flight_data['last_update']) ?></span></p>
            <a href="/" class="back-link">← Назад к индексу</a>
        </div>

        <!-- AAL -->
        <div class="section">
            <div class="aal-info">
                <div class="aal-circle" id="aal-circle" style="background:<?= $aal_levels[$aal]['color'] ?>"><?= $aal ?></div>
                <h2 id="aal-text"><?= $aal_levels[$aal]['text'] ?> активность</h2>
                <div class="aal-stats">
                    <div><strong id="active-count"><?= $active ?></strong> активных</div>
                    <div><strong id="total-count"><?= $flight_data['total'] ?></strong> всего</div>
                </div>
            </div>
            <p class="sources">Источник: <span id="source-text"><?= esc($flight_data['source']) ?></span></p>
            <p class="sync-status">Синхронизация: Активна</p>
            <p class="update-status" id="update-status">Обновление через <span id="countdown">60:00</span></p>
        </div>

        <!-- РЕЙСЫ -->
        <div class="section">
            <h2>Активные миссии</h2>
            <div id="flights-container">
                <?php if (empty($flight_data['flights'])): ?>
                <div class="no-flights">Нет активных VIP-рейсов. Мониторинг продолжается.</div>
                <?php else: ?>
                <?php foreach ($flight_data['flights'] as $f): ?>
                <div class="flight-card">
                    <h3>
                        <a href="<?= esc($f['source_url']) ?>" target="_blank" class="callsign-link"><?= esc($f['callsign']) ?></a>
                        <span class="status status-<?= $f['status'] === 'на земле' ? 'ground' : 'flight' ?>">
                            <?= $f['status'] === 'на земле' ? 'на земле' : 'в полёте' ?>
                        </span>
                    </h3>
                    <p><strong>Самолёт:</strong> <?= esc($f['aircraft_type']) ?> | <strong>Оператор:</strong> <?= esc($f['operator']) ?></p>
                    <p><strong>Местоположение:</strong> <?= esc($f['location']) ?></p>
                    <p><strong>Цель:</strong> <?= esc($f['purpose']) ?></p>
                    <p><strong>Динамика:</strong> <?= esc($f['dynamics']) ?></p>
                    <?php if (isset($f['weight'])): ?>
                    <p><strong>Вес AAL:</strong> <?= number_format($f['weight'], 1) ?></p>
                    <?php endif; ?>
                </div>
                <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </div>

        <!-- ШКАЛА AAL -->
        <div class="section">
            <h2>Шкала AAL</h2>
            <div class="aal-scale">
                <div class="aal-block <?= $aal == 1 ? 'active' : '' ?>"><div>1</div><span>Нормальная<br>0–1.9</span></div>
                <div class="aal-block <?= $aal == 2 ? 'active' : '' ?>"><div>2</div><span>Повышенная<br>2–3.4</span></div>
                <div class="aal-block <?= $aal == 3 ? 'active' : '' ?>"><div>3</div><span>Высокая<br>3.5–4.9</span></div>
                <div class="aal-block <?= $aal == 4 ? 'active' : '' ?>"><div>4</div><span>Критическая<br>5–6.9</span></div>
                <div class="aal-block <?= $aal == 5 ? 'active' : '' ?>"><div>5</div><span>Экстремальная<br>7+</span></div>
            </div>
            <p style="font-size:.8rem;text-align:center;color:#94a3b8;">
                Текущий взвешенный: <span id="weighted-value"><?= number_format($weighted_active, 1) ?></span>
            </p>
        </div>
    </div>

    <div class="sidebar">
        <div class="section">
            <h3>Пороги тревоги</h3>
            <div class="aal-thresholds">
                <div class="threshold threshold-1"><span>1 – 0–1.9</span><div class="threshold-bar"><div class="threshold-fill"></div></div></div>
                <div class="threshold threshold-2"><span>2 – 2–3.4</span><div class="threshold-bar"><div class="threshold-fill"></div></div></div>
                <div class="threshold threshold-3"><span>3 – 3.5–4.9</span><div class="threshold-bar"><div class="threshold-fill"></div></div></div>
                <div class="threshold threshold-4"><span>4 – 5–6.9</span><div class="threshold-bar"><div class="threshold-fill"></div></div></div>
                <div class="threshold threshold-5"><span>5 – 7+</span><div class="threshold-bar"><div class="threshold-fill"></div></div></div>
            </div>
            <p style="margin-top:.5rem;font-size:.8rem;text-align:center;">Текущий: <span class="current-aal" id="sidebar-aal"><?= $aal ?></span></p>
        </div>

        <div class="section">
            <h3>Статистика</h3>
            <p>Активных: <strong id="stats-active"><?= $active ?></strong></p>
            <p>Всего: <strong id="stats-total"><?= $flight_data['total'] ?></strong></p>
            <p>Взвешенный: <strong id="stats-weighted"><?= number_format($weighted_active, 1) ?></strong></p>
        </div>

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

<div class="footer">
    <p><strong>Avatiah Security Index</strong> © 2025</p>
    <p><a href="https://github.com/avatiah" target="_blank">GitHub</a> • <a href="https://t.me/avatiah" target="_blank">Telegram</a></p>
</div>

<script>
    const js = <?= $js_data ?>;
    const UPDATE_INTERVAL_MINUTES = <?= $update_interval ?>;
    let countdownInterval;

    function updateDOM(data) {
        document.getElementById('aal-value').textContent = data.aal;
        document.getElementById('aal-circle').textContent = data.aal;
        document.getElementById('aal-circle').style.background = data.aal_color;
        document.getElementById('aal-text').textContent = data.aal_text + ' активность';
        document.getElementById('sidebar-aal').textContent = data.aal;
        document.getElementById('active-count').textContent = data.active_flights;
        document.getElementById('total-count').textContent = data.total_flights;
        document.getElementById('stats-active').textContent = data.active_flights;
        document.getElementById('stats-total').textContent = data.total_flights;
        document.getElementById('stats-weighted').textContent = Number(data.weighted_active).toFixed(1);
        document.getElementById('weighted-value').textContent = Number(data.weighted_active).toFixed(1);
        document.getElementById('source-text').textContent = data.source;
        document.getElementById('last-update').textContent = data.last_update;
        document.getElementById('sidebar-update').textContent = new Date().toTimeString().slice(0,5);

        const container = document.getElementById('flights-container');
        container.innerHTML = '';
        if (!data.flights.length) {
            container.innerHTML = '<div class="no-flights">Нет активных VIP-рейсов. Мониторинг продолжается.</div>';
        } else {
            data.flights.forEach(f => {
                const div = document.createElement('div');
                div.className = 'flight-card';
                div.innerHTML = `
                    <h3>
                        <a href="${f.source_url}" target="_blank" class="callsign-link">${f.callsign}</a>
                        <span class="status status-${f.status === 'на земле' ? 'ground' : 'flight'}">
                            ${f.status === 'на земле' ? 'на земле' : 'в полёте'}
                        </span>
                    </h3>
                    <p><strong>Самолёт:</strong> ${f.aircraft_type} | <strong>Оператор:</strong> ${f.operator}</p>
                    <p><strong>Местоположение:</strong> ${f.location}</p>
                    <p><strong>Цель:</strong> ${f.purpose}</p>
                    <p><strong>Динамика:</strong> ${f.dynamics}</p>
                    ${f.weight !== undefined ? `<p><strong>Вес AAL:</strong> ${Number(f.weight).toFixed(1)}</p>` : ''}
                `;
                container.appendChild(div);
            });
        }

        document.getElementById('update-status').textContent = 'Обновлено!';
        setTimeout(() => document.getElementById('update-status').textContent = 'Обновление через 60:00', 3000);
    }

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

    function startCountdown() {
        const now = Date.now();
        const next = Math.ceil(now / (UPDATE_INTERVAL_MINUTES * 60 * 1000)) * (UPDATE_INTERVAL_MINUTES * 60 * 1000);
        let remaining = next - now;

        countdownInterval = setInterval(() => {
            remaining -= 1000;
            const min = String(Math.floor(remaining / 60000)).padStart(2, '0');
            const sec = String(Math.floor((remaining % 60000) / 1000)).padStart(2, '0');
            document.getElementById('countdown').textContent = `${min}:${sec}`;
            document.getElementById('next-update').textContent = new Date(next).toTimeString().slice(0, 5);
            if (remaining <= 0) {
                clearInterval(countdownInterval);
                fetchData().then(startCountdown);
            }
        }, 1000);
    }

    startCountdown();
    setTimeout(fetchData, 30000);
</script>
</body>
</html>