#!/usr/bin/env php
<?php
/**
 * Email Queue Worker
 *
 * Procesa la cola `alertas_email` (EstadoEnvio=1) y envia los correos
 * pendientes via MailService (PHPMailer/SMTP).
 *
 * Estados (EstadoEnvio):
 *   1 = Pendiente
 *   2 = Enviado
 *   3 = Error
 *
 * Uso:
 *   php bin/email-queue              # procesa hasta `correos_diarios` pendientes
 *   php bin/email-queue --limit=N    # override del limite por corrida
 *   php bin/email-queue --json       # salida JSON
 *   php bin/email-queue --dry-run    # lista pendientes sin enviar
 *
 * Programar via cron (ej. cada 5 min):
 *   * /5 * * * * php /ruta/timeklee2/bin/email-queue --json >> /var/log/email-queue.log 2>&1
 *
 * Respeta la flag `Configuraciones.DetenerEnvioNotificaciones`.
 */

$basePath = dirname(__DIR__);
define('BASE_PATH', $basePath . '/');

require $basePath . '/vendor/autoload.php';
require $basePath . '/core/helpers/Env.php';
Env::load($basePath . '/.env');

if (file_exists($basePath . '/app/config/Config.php')) {
    require $basePath . '/app/config/Config.php';
}
if (file_exists($basePath . '/app/config/ConfigEnv.php')) {
    require $basePath . '/app/config/ConfigEnv.php';
}

require_once $basePath . '/core/MailService.php';

// â”€â”€â”€ argumentos â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$args = array_slice($argv, 1);
$asJson = in_array('--json', $args, true);
$dryRun = in_array('--dry-run', $args, true);
$limitOverride = null;
foreach ($args as $a) {
    if ($a === '--help' || $a === '-h') {
        echo "Uso: php bin/email-queue [--limit=N] [--json] [--dry-run]\n";
        exit(0);
    }
    if (strpos($a, '--limit=') === 0) {
        $limitOverride = max(1, (int)substr($a, 8));
    }
}

$out = function ($msg) use ($asJson) {
    if (!$asJson) {
        echo $msg . "\n";
    }
};

// â”€â”€â”€ conexion BD â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$dbConfig = null;
if (class_exists('ConfigEnv') && property_exists('ConfigEnv', 'DB_CONNECTIONS')) {
    $connections = ConfigEnv::$DB_CONNECTIONS;
    if (isset($connections['klee'])) {
        $dbConfig = $connections['klee'];
    }
}
if (!$dbConfig) {
    fwrite(STDERR, "[error] Configuracion de BD no encontrada.\n");
    exit(1);
}

try {
    $port = isset($dbConfig['port']) && $dbConfig['port'] !== '' ? $dbConfig['port'] : '3306';
    $dsn = "mysql:host={$dbConfig['host']};port={$port};dbname={$dbConfig['dbname']};charset=utf8mb4";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['password']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    fwrite(STDERR, "[error] Conexion BD: " . $e->getMessage() . "\n");
    exit(1);
}

// â”€â”€â”€ flag de detencion â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$detenido = false;
try {
    $st = $pdo->prepare("SELECT Valor FROM configuraciones WHERE Nombre = 'DetenerEnvioNotificaciones' LIMIT 1");
    $st->execute();
    $row = $st->fetch();
    if ($row && !empty($row['Valor'])) {
        $detenido = true;
    }
} catch (PDOException $e) {
    // tabla puede no existir; ignorar.
}

if ($detenido) {
    $payload = array('ok' => true, 'detenido' => true, 'sent' => 0, 'failed' => 0, 'pending' => 0);
    if ($asJson) {
        echo json_encode($payload) . "\n";
    } else {
        $out('[info] Envio de notificaciones DETENIDO por configuracion (DetenerEnvioNotificaciones).');
    }
    exit(0);
}

// â”€â”€â”€ limite â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$limit = $limitOverride;
if ($limit === null) {
    $limit = (int)(getenv('CORREOS_DIARIOS') ?: 50);
    if ($limit <= 0) {
        $limit = 50;
    }
}

// â”€â”€â”€ cargar pendientes â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$sel = $pdo->prepare("SELECT Id, Tipo, Plantilla, Asunto, Descripcion, Destinatarios
                      FROM alertas_email
                      WHERE EstadoEnvio = 1
                      ORDER BY Id ASC
                      LIMIT " . (int)$limit);
$sel->execute();
$pendientes = $sel->fetchAll();
$total = count($pendientes);

$out("[info] Pendientes a procesar: {$total} (limit={$limit})");

if ($dryRun) {
    $rows = array();
    foreach ($pendientes as $p) {
        $rows[] = array(
            'Id' => (int)$p['Id'],
            'Tipo' => $p['Tipo'],
            'Plantilla' => $p['Plantilla'],
            'Asunto' => $p['Asunto'],
            'Destinatarios' => $p['Destinatarios'],
        );
    }
    if ($asJson) {
        echo json_encode(array('ok' => true, 'dryRun' => true, 'pending' => $total, 'rows' => $rows)) . "\n";
    } else {
        foreach ($rows as $r) {
            $out("  #{$r['Id']} [{$r['Tipo']}] {$r['Asunto']} -> {$r['Destinatarios']}");
        }
    }
    exit(0);
}

// â”€â”€â”€ config SMTP â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$emailConfig = array(
    'EmailHost' => getenv('MAIL_HOST') ?: '',
    'EmailPuerto' => getenv('MAIL_PORT') ?: '587',
    'EmailUsuario' => getenv('MAIL_USER') ?: '',
    'EmailContrasena' => getenv('MAIL_PASS') ?: '',
    'EmailEncripcion' => getenv('MAIL_ENCRYPTION') ?: 'tls',
    'EmailNombre' => getenv('MAIL_NAME') ?: 'Sistema',
    'EmailFrom' => getenv('MAIL_FROM') ?: '',
);

if ($emailConfig['EmailHost'] === '' || $emailConfig['EmailUsuario'] === '') {
    fwrite(STDERR, "[error] SMTP no configurado (MAIL_HOST/MAIL_USER vacios en .env).\n");
    exit(1);
}

// â”€â”€â”€ enviar â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
$upd = $pdo->prepare("UPDATE alertas_email
                      SET EstadoEnvio = :est, Comentarios = :com
                      WHERE Id = :id");
$sent = 0;
$failed = 0;
$results = array();

foreach ($pendientes as $alerta) {
    $id = (int)$alerta['Id'];
    $destinatarios = preg_split('/[\s,;]+/', (string)$alerta['Destinatarios']);
    $destinatarios = array_filter(array_map('trim', $destinatarios ?: array()));

    if (count($destinatarios) === 0) {
        $upd->execute(array(':est' => 3, ':com' => 'Sin destinatarios validos.', ':id' => $id));
        $failed++;
        $out("[err] Sin destinatarios #{$id}");
        $results[] = array('id' => $id, 'status' => 'failed', 'error' => 'no_recipients');
        continue;
    }

    try {
        $result = MailService::send(
            $destinatarios,
            $alerta['Asunto'],
            $alerta['Descripcion'],
            $emailConfig,
            array('isHtml' => true)
        );

        if (!empty($result['success'])) {
            $upd->execute(array(':est' => 2, ':com' => $result['message'] ?? 'Enviado', ':id' => $id));
            $sent++;
            $out("[ok] Enviado #{$id} -> " . implode(',', $destinatarios));
            $results[] = array('id' => $id, 'status' => 'sent');
        } else {
            $upd->execute(array(':est' => 3, ':com' => $result['message'] ?? 'Error desconocido.', ':id' => $id));
            $failed++;
            $out("[err] Fallo #{$id}: " . ($result['message'] ?? 'sin detalle'));
            $results[] = array('id' => $id, 'status' => 'failed', 'error' => $result['message'] ?? null);
        }
    } catch (Throwable $e) {
        $upd->execute(array(':est' => 3, ':com' => 'Excepcion: ' . $e->getMessage(), ':id' => $id));
        $failed++;
        $out("[err] Excepcion #{$id}: " . $e->getMessage());
        $results[] = array('id' => $id, 'status' => 'exception', 'error' => $e->getMessage());
    }

    usleep(500000); // throttle 0.5s
}

$payload = array(
    'ok' => true,
    'pending' => $total,
    'sent' => $sent,
    'failed' => $failed,
    'detenido' => false,
);

if ($asJson) {
    $payload['results'] = $results;
    echo json_encode($payload) . "\n";
} else {
    $out("[done] sent={$sent} failed={$failed} pending_inicial={$total}");
}

exit($failed > 0 ? 2 : 0);