<?php

// Prevent web access
if (php_sapi_name() !== 'cli') {
    // Log attempt instead of just dying, but still deny access
    if (defined('ERROR_LOG_PATH')) { error_log("Attempted web access to cron_broadcast.php from " . ($_SERVER['REMOTE_ADDR'] ?? 'Unknown IP')); }
    http_response_code(403); // Forbidden
    die("Access Denied. This script is intended for CLI execution only.");
}

// Set the working directory to the project root for consistent paths
// Adjust the path '..' if your cron execution context differs
chdir(__DIR__ . '/..');

// --- Load Necessary Files ---
// Keep includes minimal for cron efficiency
require_once 'config.php'; 
require_once 'src/Database/Connection.php';
require_once 'src/Database/BroadcastQueries.php'; 
require_once 'src/Services/BotApiService.php';

// --- Configuration ---
define('MESSAGES_PER_RUN', 25); // How many messages to send per execution

echo "Cron Broadcast Job Started: " . date('Y-m-d H:i:s') . "\n";

try {
    // --- Get Next Broadcast --- //
    $broadcast = getNextPendingBroadcast(); // From BroadcastQueries.php

    if (!$broadcast) {
        echo "No pending broadcasts found to process.\n";
        exit();
    }

    $broadcast_id = $broadcast['id'];
    $message_text = $broadcast['message_text'];
    echo "Processing broadcast ID: {$broadcast_id}\n";

    // --- Fetch and Lock Jobs --- //
    // getPendingBroadcastJobs handles locking (FOR UPDATE SKIP LOCKED)
    $jobs = getPendingBroadcastJobs($broadcast_id, MESSAGES_PER_RUN); // From BroadcastQueries.php

    if (empty($jobs)) {
        // Double-check if there are truly no pending jobs left for this broadcast
        $remaining_pending = countPendingJobsForBroadcast($broadcast_id); // From BroadcastQueries.php
        if ($remaining_pending == 0) {
            echo "No more pending jobs for broadcast ID {$broadcast_id}. Finalizing...\n";
            finalizeBroadcast($broadcast_id); // From BroadcastQueries.php
        } else {
            echo "No available jobs to process currently for broadcast ID {$broadcast_id} (might be locked by another process or none left in this batch).\n";
        }
        exit();
    }

    echo "Fetched " . count($jobs) . " jobs for broadcast ID {$broadcast_id}...\n";

    // --- Process Jobs --- //
    $sent_count = 0;
    $failed_count = 0;

    foreach ($jobs as $job) {
        $status = 'failed'; // Default status
        $error_detail = null;
        try {
            // Send the message using BotApiService
            $response = apiRequest(
                'sendMessage',
                [
                    'chat_id' => $job['chat_id'],
                    'text' => $message_text,
                    'parse_mode' => 'Markdown' // Assuming Markdown
                ],
                $job['platform'] // Use platform stored in the job
            ); 

            if ($response && ($response['ok'] ?? false)) {
                $status = 'sent';
                $sent_count++;
            } else {
                // Log specific API error if available
                $error_detail = $response['description'] ?? 'Unknown API Error during broadcast';
                 if(defined('ERROR_LOG_PATH')) file_put_contents(ERROR_LOG_PATH, "Broadcast API Error (Job {$job['id']}, Chat {$job['chat_id']}, Plat {$job['platform']}): " . $error_detail . "\n", FILE_APPEND);
                $failed_count++;
            }
        } catch (Exception $e) {
            // Catch exceptions during apiRequest or other issues
            $error_detail = $e->getMessage();
            if(defined('ERROR_LOG_PATH')) file_put_contents(ERROR_LOG_PATH, "Broadcast Exception (Job {$job['id']}): " . $error_detail . "\n", FILE_APPEND);
            $failed_count++;
        }

        // Update the job status in DB
        updateBroadcastJobStatus($job['id'], $status); // From BroadcastQueries.php

        // Small delay to avoid hitting API rate limits
        usleep(150000); // 150ms delay (adjust as needed)
    }

    // --- Update Broadcast Statistics --- //
    if ($sent_count > 0 || $failed_count > 0) {
        updateBroadcastStats($broadcast_id, $sent_count, $failed_count); // From BroadcastQueries.php
    }

    echo "Batch finished. Sent: {$sent_count}, Failed: {$failed_count}\n";

    // --- Check if Broadcast is Complete --- //
    $remaining_after_batch = countPendingJobsForBroadcast($broadcast_id);
    if ($remaining_after_batch == 0) {
         echo "Broadcast ID {$broadcast_id} completed. Finalizing...\n";
         finalizeBroadcast($broadcast_id);
    }

} catch (PDOException $db_e) {
    // Catch database connection or query errors during the process
    echo "Database Error: " . $db_e->getMessage() . "\n";
    if(defined('ERROR_LOG_PATH')) file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - Cron Job DB Error: " . $db_e->getMessage() . "\n", FILE_APPEND);
} catch (Exception $e) {
    // Catch other general errors
    echo "General Error: " . $e->getMessage() . "\n";
    if(defined('ERROR_LOG_PATH')) file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - Cron Job General Error: " . $e->getMessage() . "\n", FILE_APPEND);
}

echo "Cron Broadcast Job Finished: " . date('Y-m-d H:i:s') . "\n";

?>
