<?php
session_start();
ini_set('log_errors',     '1');
ini_set('error_reporting', E_ALL);
ini_set('error_log',      __DIR__ . '/error.log');
// Force Eastern Time for all date() calls
date_default_timezone_set('America/New_York');

// ─── Assign persistent visitor ID ─────────────────────────────────────────────
if (!isset($_COOKIE['visitor_id'])) {
    $visitor_id = bin2hex(random_bytes(16));
    setcookie('visitor_id', $visitor_id, time()+365*24*60*60, '/', '', true, true);
} else {
    $visitor_id = $_COOKIE['visitor_id'];
}

// ─── LOGGING HELPER ────────────────────────────────────────────────────────────
function get_geolocation(string $ip): string {
    static $inMemory = [];
    if (isset($inMemory[$ip])) {
        return $inMemory[$ip];
    }
    $cacheDir  = __DIR__ . '/geo_cache';
    $cacheFile = "$cacheDir/$ip.json";
    if (file_exists($cacheFile) && time() - filemtime($cacheFile) < 86400) {
        $raw = file_get_contents($cacheFile);
    } else {
        if (!is_dir($cacheDir)) mkdir($cacheDir, 0755, true);
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL            => "http://ip-api.com/json/$ip?fields=status,city,regionName,country,countryCode",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT => 2,
            CURLOPT_TIMEOUT        => 3,
        ]);
        $raw = curl_exec($ch);
        curl_close($ch);
        if ($raw !== false) file_put_contents($cacheFile, $raw);
    }
    if ($raw) {
        $data = json_decode($raw, true);
        if (!empty($data['status']) && $data['status']==='success') {
            $loc = "{$data['city']}, {$data['regionName']}, {$data['country']} {$data['countryCode']}";
            return $inMemory[$ip] = $loc;
        }
    }
    return $inMemory[$ip] = 'Location Not Found';
}

function log_action(string $action): void {
    $visitor_id = $_COOKIE['visitor_id'] ?? 'unknown';
    $ip         = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    $ua         = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
    $loc        = get_geolocation($ip);
    $time       = date('Y-m-d H:i:s');
    $line       = implode(', ', [$visitor_id, $ip, $ua, $loc, $action, $time]) . "\n";
    file_put_contents(__DIR__.'/logs.txt', $line, FILE_APPEND|LOCK_EX);
}

// Log page views
if ($_SERVER['REQUEST_METHOD']==='GET' && !isset($_GET['upload'])) {
    log_action('VISIT index.php');
    if (!isset($_SESSION['logged_visit'])) {
        log_action('VISIT');
        $_SESSION['logged_visit'] = true;
    }
}
if (isset($_GET['log_view'])) {
    log_action('VIEW ' . urldecode($_GET['log_view']));
    exit;
}

// ─── VirusTotal helpers ───────────────────────────────────────────────────────
define('VT_API_KEY', '78e2de724beffa237867f5125b113a7aed68e08391e40d9c7bf3072f841d175d');

function scanWithVirusTotal(string $filePath): ?string {
    $file = curl_file_create($filePath);
    $ch = curl_init('https://www.virustotal.com/api/v3/files');
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER    => ["x-apikey: " . VT_API_KEY],
        CURLOPT_RETURNTRANSFER=> true,
        CURLOPT_POST          => true,
        CURLOPT_POSTFIELDS    => ['file' => $file],
    ]);
    $resp = curl_exec($ch);
    curl_close($ch);
    if (!$resp) return null;
    $data = json_decode($resp, true);
    return $data['data']['id'] ?? null;
}

// re‐analysis endpoint
function rescanWithVirusTotal(string $fileHash): ?string {
    global $virusTotalApiKey;
    $ch = curl_init("https://www.virustotal.com/api/v3/files/{$fileHash}/analyse");
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER    => [
            "x-apikey: {$virusTotalApiKey}",
            "Content-Type: application/json",
        ],
        CURLOPT_POST          => true,
        CURLOPT_RETURNTRANSFER=> true,
    ]);
    $resp = curl_exec($ch);
    curl_close($ch);
    if (!$resp) return null;
    $data = json_decode($resp, true);
    return $data['data']['id'] ?? null;
}

function getVirusTotalReport(string $analysisId): ?string {
    $ch = curl_init("https://www.virustotal.com/api/v3/analyses/{$analysisId}");
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER    => ["x-apikey: " . VT_API_KEY],
        CURLOPT_RETURNTRANSFER=> true,
    ]);
    $resp = curl_exec($ch);
    curl_close($ch);
    $data = json_decode($resp, true);
    return $data['meta']['file_info']['sha256'] ?? null;
}

// ─── Handle upload + VT scan ─────────────────────────────────────────────────
$uploadDir     = __DIR__ . '/uploads/';
$statusMessage = '';
$virusTotalLink= '';

if (isset($_FILES['upload'])) {
    $messages = [];
    foreach ($_FILES['upload']['error'] as $i => $err) {
        $name = basename($_FILES['upload']['name'][$i]);
        if ($err !== UPLOAD_ERR_OK) {
            $messages[] = "<p style='color:red;'>Error uploading <strong>$name</strong> (code $err).</p>";
            continue;
        }

        $tmp  = $_FILES['upload']['tmp_name'][$i];
        $dest = $uploadDir . $name;

        // 1) initial VT scan
        $analysisId = scanWithVirusTotal($tmp);
        if (!$analysisId) {
            $messages[] = "<p style='color:red;'>VT scan failed for <strong>$name</strong>. <a href='https://www.virustotal.com/gui/home/upload' target='_blank'>Manual scan</a>.</p>";
            continue;
        }

// 2) poll for report (up to 30s)
$fileHash  = null;
$timeout   = 30;    // seconds total
$interval  = 3;     // seconds between tries
$startTime = time();

while (time() - $startTime < $timeout) {
    if ($h = getVirusTotalReport($analysisId)) {
        $fileHash = $h;
        break;
    }
    sleep($interval);
}

if (!$fileHash) {
    $statusMessage = '<p style="color:red;">VT report unavailable after 30s.</p>';
            continue;
        }

        // 3) optional re-scan if too old (reuse your last_scanned logic here…)
$scanTimestampFile = __DIR__ . '/uploads/' . $name . '.last_scanned';
$doRescan = false;
if (file_exists($scanTimestampFile)) {
    // how many seconds since last scan?
    $age = time() - (int)file_get_contents($scanTimestampFile);
    if ($age > 12 * 3600) { // older than 12 hours
        $doRescan = true;
    }
} else {
    // never scanned before
    $doRescan = true;
}

if ($doRescan) {
    // trigger a fresh VT analysis
    $newAnalysisId = rescanWithVirusTotal($fileHash);
    if ($newAnalysisId) {
        // poll for the new report
        for ($i = 0; $i < 5; $i++) {
            sleep(2);
            if ($h2 = getVirusTotalReport($newAnalysisId)) {
                $fileHash = $h2;
                break;
            }
        }
    }
}

// record that we just scanned
file_put_contents($scanTimestampFile, (string)time());
        // 4) move into uploads
        if (!move_uploaded_file($tmp, $dest)) {
            $messages[] = "<p style='color:red;'>Failed to save <strong>$name</strong>.</p>";
            continue;
        }

        // 5) log & build link
        log_action("Uploaded photo $name");
        $vtLink = "https://www.virustotal.com/gui/file/$fileHash";
        $messages[] = 
          "<p style='color:green;'>Uploaded <strong>$name</strong>. "
         . "<a href='$vtLink' target='_blank'>View VT report</a></p>";
    }

    // show all results
    $statusMessage = implode("\n", $messages);
}


// ─── Gather & sort uploaded images ───────────────────────────────────────────
// only include real, non-empty JPEG/PNG/GIF files
$images = [];
foreach (scandir($uploadDir) as $f) {
    $path = $uploadDir . $f;
    if ($f === '.' || $f === '..')      continue;
    if (!is_file($path))                 continue;
    if (filesize($path) === 0)           continue;
    // suppress any getimagesize warnings
    if (@getimagesize($path) === false)  continue;
    $images[] = $f;
}
// pick up ?sort=newest or ?sort=oldest
$order = $_GET['sort'] ?? 'newest';

if ($order === 'oldest') {
    // oldest first
    usort($images, function($a, $b) use ($uploadDir) {
        return filemtime($uploadDir . $a) <=> filemtime($uploadDir . $b);
    });
} else {
    // newest first
    usort($images, function($a, $b) use ($uploadDir) {
        return filemtime($uploadDir . $b) <=> filemtime($uploadDir . $a);
    });
}


?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Adam's Gallery</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: Arial, sans-serif; background-color: #f8f9fa; color: #333; padding: 20px; text-align: center; }
        h1 { font-size: 2.5rem; margin-bottom: 20px; }
        #gallery { column-count: 3; column-gap: 1em; max-width: 1200px; margin: 30px auto; }
        .cat-photo { width: 100%; margin-bottom: 1em; border-radius: 10px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); transition: transform .3s; cursor: zoom-in; }
        .cat-photo:hover { transform: scale(1.02); }
        .upload-form { margin-top: 40px; padding: 10px; background-color: #fff; border: 1px solid #ddd; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
        input[type="file"], input[type="submit"] { padding: 10px; border-radius: 5px; }
        input[type="submit"] { background-color: #28a745; color: white; cursor: pointer; }
        input[type="submit"]:hover { background-color: #218838; }
        button { padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; }
        button:hover { background-color: #0056b3; }
#overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
    display: none; /* Ensures it stays hidden initially */
    z-index: 999;
}

#overlay.active {
    display: block; /* Only shows when zooming */
}
.cat-photo.expanded {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    max-width: 90vw;
    max-height: 90vh;
    width: auto;
    height: auto;
    object-fit: contain;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
    cursor: zoom-out;
    z-index: 1000; /* Ensures image stays above the overlay */
}
    .sort-buttons {
    margin: 20px 0;
    text-align: center;
}

.sort-buttons button {
    background-color: #007bff;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 16px;
    transition: background-color 0.3s;
}

.sort-buttons button:hover {
    background-color: #0056b3;
}
	</style>
</head>
<body>
<div style="text-align:right;margin-bottom:10px;">
  <a href="index.php"><button>Home</button></a>
  <a href="admin.php"><button>Admin Panel</button></a>
  <a href="?logout=1"><button>Logout</button></a>
</div>
<h1>Mickey’s Gallery</h1>
<?php if ($statusMessage): ?>
  <?= $statusMessage /* already contains your <p>…</p> */ ?>
<?php endif; ?>


<form method="post" enctype="multipart/form-data" class="upload-form">
<input type="file" name="upload[]" multiple required>

  <input type="submit" name="upload" value="Upload">
</form>

<div class="sort-buttons">
  <button onclick="location='?sort=newest'">Newest First</button>
  <button onclick="location='?sort=oldest'">Oldest First</button>
</div>
<div id="overlay"></div>
<div id="gallery">
  <?php foreach($images as $img): ?>
    <img src="/mickey/uploads/<?= htmlspecialchars($img) ?>" class="cat-photo">
  <?php endforeach; ?>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
    const overlay = document.getElementById("overlay");
    const images = document.querySelectorAll(".cat-photo");

    images.forEach(image => {
        image.addEventListener("click", function () {
            if (this.classList.contains("expanded")) {
                this.classList.remove("expanded");
                overlay.classList.remove("active");
                overlay.style.display = "none"; // Hide overlay properly
            } else {
                this.classList.add("expanded");
                overlay.classList.add("active");
                overlay.style.display = "block"; // Show overlay only when zooming
            }
        });
    });

    overlay.addEventListener("click", function () {
        images.forEach(image => image.classList.remove("expanded"));
        overlay.classList.remove("active");
        overlay.style.display = "none"; // Hide overlay when clicking outside image
    });
});

    // ─── Disable right-click & DevTools ─────────────────────────────────────────
    document.addEventListener('contextmenu', e => e.preventDefault());
    document.addEventListener('keydown', e => {
        if (e.keyCode === 123 || // F12
            (e.ctrlKey && e.shiftKey && (e.keyCode === 73
                || e.keyCode === 74)) ||      // Ctrl+Shift+I/J
            (e.ctrlKey && e.keyCode === 85)                        // Ctrl+U
        ) {
            e.preventDefault();
        }
    });
</script>
</body>
</html>