<?php
declare(strict_types=1);
/* ====================================================
SAFETY TALK SYSTEM - PT CITRA LAMPIA MANDIRI
File        : export_csv.php
Versi       : 2.5.0
Revisi      : 001 - Support CSV 10 kolom (peserta_seharusnya)
Fitur       : - ✅ Export filtered data to CSV
              - ✅ CSV Structure: 10 columns [0-9]
              - ✅ Field "peserta_seharusnya" (index 8)
              - ✅ Authentication Check
              - ✅ CSV Injection Prevention
              - ✅ UTF-8 BOM for Excel compatibility
              - ✅ Input sanitization & validation
              - ✅ Activity logging
              - ✅ Rate limiting (60s cooldown)
              
📋 CSV Structure Export (10 columns):
  [0]Tanggal, [1]Hari, [2]Departemen, [3]Divisi, 
  [4]Nama PIC, [5]Jabatan, [6]Topik Materi, 
  [7]Jumlah Peserta, [8]Peserta Seharusnya, [9]Nama File Foto
====================================================
*/

// ===== KONFIGURASI GLOBAL (Readonly Class - PHP 8.2+) =====
final readonly class AppConfig
{
    public function __construct(
        public string $appVersion = '2.5.0',
        public string $revision = '001',
        public string $timezone = 'Asia/Jakarta',
        public int $exportCooldownSeconds = 60,
        public int $sessionTimeout = 1800,
    ) {}
}

$config = new AppConfig();
date_default_timezone_set($config->timezone);

// ===== AUTH & SECURITY CHECK =====
if(session_status() === PHP_SESSION_NONE && !@session_start()) {
    error_log('[EXPORT_CSV] Failed to start session');
    exit('❌ Gagal memulai sesi. Hubungi administrator.');
}

// 🔐 Cek login - critical security fix
if(!isset($_SESSION['user_logged_in']) || $_SESSION['user_logged_in'] !== true) {
    error_log(sprintf(
        "[EXPORT_DENIED] IP:%s Time:%s - Unauthenticated access attempt\n",
        $_SERVER['REMOTE_ADDR'] ?? 'unknown',
        date('c')
    ));
    header('Location: login.php?access_denied=1');
    exit;
}

// Session timeout check
if(isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > $config->sessionTimeout)) {
    session_unset();
    session_destroy();
    header('Location: login.php?timeout=1');
    exit;
}
$_SESSION['last_activity'] = time();

// ===== RATE LIMITING (Prevent abuse) =====
if(isset($_SESSION['last_export_time']) && (time() - $_SESSION['last_export_time'] < $config->exportCooldownSeconds)) {
    $remaining = $config->exportCooldownSeconds - (time() - $_SESSION['last_export_time']);
    exit("⚠️ Silakan tunggu {$remaining} detik sebelum export lagi.");
}
$_SESSION['last_export_time'] = time();

// ===== LOG EXPORT ACTIVITY =====
function logExportActivity(string $user, array $filters, string $logPath): void
{
    $header = ['timestamp', 'user', 'ip', 'filters'];
    $logDir = dirname($logPath);
    
    if(!is_dir($logDir) && !@mkdir($logDir, 0755, true)) {
        return;
    }
    
    $file = @fopen($logPath, 'a');
    if($file === false) return;
    
    $exists = filesize($logPath) > 0;
    if(!$exists) @fputcsv($file, $header);
    
    @fputcsv($file, [
        date('Y-m-d H:i:s'),
        $user,
        $_SERVER['REMOTE_ADDR'] ?? 'unknown',
        http_build_query($filters)
    ]);
    fclose($file);
}

// ===== CSV INJECTION PREVENTION =====
/**
 * Sanitize cell value to prevent CSV formula injection
 * Dangerous prefixes: =, +, -, @, tab, newline
 */
function sanitizeCSVCell(mixed $value): string
{
    $value = (string)$value;
    if(preg_match('/^[=+\-@\t\r\n]/', $value)) {
        return "'" . $value;
    }
    return str_replace('"', '""', $value);
}

function sanitizeCSVRow(array $row): array
{
    return array_map('sanitizeCSVCell', $row);
}

// ===== GET & SANITIZE FILTER PARAMETERS =====
$f_start  = isset($_GET['start']) ? preg_replace('/[^\d\-]/', '', $_GET['start']) : '';
$f_end    = isset($_GET['end']) ? preg_replace('/[^\d\-]/', '', $_GET['end']) : '';
$f_divisi = isset($_GET['divisi']) ? trim($_GET['divisi']) : '';
$f_search = isset($_GET['search']) ? trim($_GET['search']) : '';

// Validate date format if provided
if($f_start && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $f_start)) $f_start = '';
if($f_end && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $f_end)) $f_end = '';

// ===== PREPARE FILENAME (Safe, no user input) =====
$timestamp = date('Ymd_His');
$username_safe = preg_replace('/[^a-zA-Z0-9_\-.]/', '_', $_SESSION['user_name'] ?? 'user');
$filename = "Rekap_SafetyTalk_{$timestamp}_{$username_safe}.csv";

// ===== HTTP HEADERS FOR CSV DOWNLOAD =====
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Pragma: no-cache');
header('Expires: 0');

// ===== OUTPUT UTF-8 BOM FOR EXCEL COMPATIBILITY =====
echo "\xEF\xBB\xBF";

// ===== OPEN OUTPUT STREAM =====
$output = @fopen('php://output', 'w');
if($output === false) {
    error_log("[EXPORT_ERROR] Failed to open output stream");
    exit('❌ Gagal memulai export. Hubungi administrator.');
}

// ===== WRITE CSV HEADER (10 Columns) =====
$csvHeader = [
    'Tanggal', 
    'Hari', 
    'Departemen', 
    'Divisi', 
    'Nama PIC', 
    'Jabatan', 
    'Topik Materi', 
    'Jumlah Peserta', 
    'Peserta Seharusnya', // ✅ NEW COLUMN
    'Nama File Foto'
];
fputcsv($output, $csvHeader);

// ===== LOAD & FILTER DATA =====
$csvPath = __DIR__ . '/data/safety_talk.csv';
$exportedCount = 0;

if(file_exists($csvPath) && is_readable($csvPath)) {
    $file = @fopen($csvPath, 'r');
    if($file !== false) {
        while(($row = @fgetcsv($file, 1000, ",")) !== false) {
            // ✅ Validasi minimal 9 kolom (data lama) atau 10 kolom (data baru)
            if(!is_array($row) || count($row) < 9) continue;
            
            $tanggal = trim($row[0] ?? '');
            if(empty($tanggal)) continue;

            // Apply filters (same logic as rekap.php)
            $pass = true;
            
            if($f_start && $tanggal < $f_start) $pass = false;
            if($f_end && $tanggal > $f_end) $pass = false;
            
            $divisi = trim($row[3] ?? '');
            if($f_divisi && $divisi !== $f_divisi) $pass = false;
            
            if($f_search) {
                $nama = trim($row[4] ?? '');
                $topik = trim($row[6] ?? '');
                $searchStr = $nama . " " . $topik;
                if(stripos($searchStr, $f_search) === false) $pass = false;
            }

            // If passes filters, export with sanitization
            if($pass) {
                // ✅ Handle backward compatibility: jika hanya 9 kolom, tambahkan peserta_seharusnya
                if(count($row) === 9) {
                    // Insert peserta_seharusnya (index 8) = peserta (index 7)
                    array_splice($row, 8, 0, [$row[7]]);
                }
                
                // ✅ Sanitize row to prevent CSV injection
                $safeRow = sanitizeCSVRow($row);
                fputcsv($output, $safeRow);
                $exportedCount++;
            }
        }
        fclose($file);
    }
}

fclose($output);

// ===== LOG SUCCESSFUL EXPORT =====
logExportActivity(
    $_SESSION['user_name'] ?? 'unknown', 
    [
        'start' => $f_start,
        'end' => $f_end,
        'divisi' => $f_divisi,
        'search' => $f_search,
        'count' => $exportedCount
    ],
    __DIR__ . '/data/export_log.csv'
);

// ✅ Clean exit
exit;