<?php

declare(strict_types=1);

/**
 * Drain the platform email retry queue.
 *
 * Messages that failed on every configured SMTP server (see Settings → Email Server
 * → Fallback servers) are persisted by \PpPhp\Core\MailQueue and retried with
 * backoff. A normal web request already drains a few every couple of minutes; this
 * CLI drains bigger backlogs faster and is what you point cron at where cron exists.
 *
 * USAGE (CLI only):
 *   php bin/mail-queue.php            # process up to 200 due messages, print stats
 *   php bin/mail-queue.php --limit=500
 *   php bin/mail-queue.php --status   # just print pending / failed counts
 *   php bin/mail-queue.php --retry-failed   # move dead-lettered mail back into the queue
 *
 * CRON (every 5 minutes):
 *   * /5 * * * * php /path/to/public_html/bin/mail-queue.php >/dev/null 2>&1
 */

if (PHP_SAPI !== 'cli') {
    http_response_code(403);
    exit("This script runs on the command line only.\n");
}

define('BASE_PATH', dirname(__DIR__));

$__tz = (string) (((array) (is_file(BASE_PATH . '/config/app.php') ? require BASE_PATH . '/config/app.php' : []))['timezone'] ?? 'Asia/Kathmandu');
if ($__tz !== '') { @date_default_timezone_set($__tz); if (!defined('PP_TIMEZONE')) define('PP_TIMEZONE', $__tz); }

require_once BASE_PATH . '/core/Autoloader.php';
$autoloader = new \PpPhp\Core\Autoloader();
$autoloader->addNamespace('PpPhp\\Core\\', BASE_PATH . '/core/');
$autoloader->register();
require_once BASE_PATH . '/core/Helpers.php';

// The queue calls PlatformSettings::primeMailer(), which reads platform settings
// from the database — so a configured install is required.
if (is_file(BASE_PATH . '/config/database.php')) {
    $dbConfig = require BASE_PATH . '/config/database.php';
    $container = new \PpPhp\Core\Container();
    $container->set(\PpPhp\Core\Config::class, new \PpPhp\Core\Config(['db_config' => new \PpPhp\Core\Config($dbConfig)]));
}

use PpPhp\Core\MailQueue;

$args = $argv;
$opt = static function (string $name, $default = null) use ($args) {
    foreach ($args as $a) {
        if ($a === '--' . $name) return true;
        if (str_starts_with($a, '--' . $name . '=')) return substr($a, strlen($name) + 3);
    }
    return $default;
};

if ($opt('status')) {
    echo 'Mail queue: ' . MailQueue::pending() . ' pending, ' . MailQueue::failedCount() . " failed.\n";
    exit(0);
}

if ($opt('retry-failed')) {
    $n = MailQueue::retryFailed();
    echo "Re-queued {$n} dead-lettered message(s).\n";
    // fall through and try to send them right away
}

$limit = (int) ($opt('limit', 200));
$stats = MailQueue::process($limit > 0 ? $limit : 200);

printf(
    "Processed %d: sent %d, retried %d, dead-lettered %d. %d still pending.\n",
    $stats['processed'], $stats['sent'], $stats['retried'], $stats['failed'], $stats['pending']
);
exit(0);
