<?php
/**
 * SMTP mailer sin dependencias externas.
 * Soporta SSL (port 465), STARTTLS (port 587) y sin cifrado.
 * Config guardada en sync_state con prefijo smtp_.
 */

function smtpGetConfig(PDO $pdo): array
{
    $rows = $pdo->query("SELECT state_key, state_value FROM sync_state WHERE state_key LIKE 'smtp_%'")->fetchAll();
    $cfg  = [];
    foreach ($rows as $r) {
        $cfg[substr($r['state_key'], 5)] = $r['state_value']; // strip 'smtp_'
    }
    return array_merge([
        'host'       => '',
        'port'       => '587',
        'encryption' => 'tls',
        'user'       => '',
        'pass'       => '',
        'from_email' => '',
        'from_name'  => 'ZeroTrust Shield',
        'enabled'    => '0',
    ], $cfg);
}

function smtpSaveConfig(PDO $pdo, array $cfg): void
{
    $map = [
        'smtp_host'       => $cfg['host']       ?? '',
        'smtp_port'       => $cfg['port']        ?? '587',
        'smtp_encryption' => $cfg['encryption']  ?? 'tls',
        'smtp_user'       => $cfg['user']        ?? '',
        'smtp_from_email' => $cfg['from_email']  ?? '',
        'smtp_from_name'  => $cfg['from_name']   ?? 'ZeroTrust Shield',
        'smtp_enabled'    => $cfg['enabled']     ?? '0',
    ];
    // Contraseña: solo actualizar si viene con valor
    if (!empty($cfg['pass'])) {
        $map['smtp_pass'] = $cfg['pass'];
    }
    $stmt = $pdo->prepare("
        INSERT INTO sync_state (state_key, state_value)
        VALUES (?, ?)
        ON DUPLICATE KEY UPDATE state_value = VALUES(state_value)
    ");
    foreach ($map as $key => $val) {
        $stmt->execute([$key, $val]);
    }
}

/**
 * Envía un email HTML. Usa SMTP si está configurado y activo, sino mail().
 * Lanza RuntimeException si falla.
 */
function sendMail(PDO $pdo, string $to, string $subject, string $htmlBody): bool
{
    $cfg = smtpGetConfig($pdo);

    if ($cfg['enabled'] === '1' && !empty($cfg['host'])) {
        return smtpSend($cfg, $to, $subject, $htmlBody);
    }

    // Fallback: PHP mail()
    $headers = implode("\r\n", [
        'MIME-Version: 1.0',
        'Content-Type: text/html; charset=UTF-8',
        'Content-Transfer-Encoding: base64',
        'From: ZeroTrust Shield <' . (APP_URL ? parse_url(APP_URL, PHP_URL_HOST) : 'localhost') . '>',
    ]);
    if (!mail($to, $subject, base64_encode($htmlBody), $headers)) {
        throw new RuntimeException("mail() falló para $to");
    }
    return true;
}

function smtpSend(array $cfg, string $to, string $subject, string $htmlBody): bool
{
    $host       = $cfg['host'];
    $port       = (int)($cfg['port'] ?: 587);
    $encryption = $cfg['encryption'] ?: 'tls'; // 'ssl' | 'tls' | 'none'
    $user       = $cfg['user'];
    $pass       = $cfg['pass'];
    $fromEmail  = $cfg['from_email'];
    $fromName   = $cfg['from_name'] ?: 'ZeroTrust Shield';

    $socketHost = $encryption === 'ssl' ? "ssl://$host" : $host;
    $sock = @fsockopen($socketHost, $port, $errno, $errstr, 20);
    if (!$sock) {
        throw new RuntimeException("No se pudo conectar a $host:$port — $errstr ($errno)");
    }
    stream_set_timeout($sock, 20);

    $read = function () use ($sock): string {
        $data = '';
        while ($line = fgets($sock, 512)) {
            $data .= $line;
            // Fin de respuesta multi-línea cuando el 4to char es espacio
            if (strlen($line) >= 4 && $line[3] === ' ') break;
        }
        return $data;
    };

    $write = function (string $cmd) use ($sock): void {
        fwrite($sock, $cmd . "\r\n");
    };

    $expect = function (int $code) use ($read): string {
        $r = $read();
        if (substr(trim($r), 0, 3) !== (string)$code) {
            throw new RuntimeException("SMTP error (esperado $code): " . trim($r));
        }
        return $r;
    };

    $expect(220);

    $hostname = gethostname() ?: 'localhost';
    $write("EHLO $hostname");
    $read(); // respuesta multi-línea

    if ($encryption === 'tls') {
        $write("STARTTLS");
        $expect(220);
        if (!stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
            throw new RuntimeException("STARTTLS falló — verificá host/puerto/certificado");
        }
        $write("EHLO $hostname");
        $read();
    }

    if (!empty($user)) {
        $write("AUTH LOGIN");
        $expect(334);
        $write(base64_encode($user));
        $expect(334);
        $write(base64_encode($pass));
        $expect(235);
    }

    $write("MAIL FROM:<$fromEmail>");
    $expect(250);
    $write("RCPT TO:<$to>");
    $expect(250);
    $write("DATA");
    $expect(354);

    $encSubject  = '=?UTF-8?B?' . base64_encode($subject)  . '?=';
    $encFromName = '=?UTF-8?B?' . base64_encode($fromName) . '?=';

    $msg = implode("\r\n", [
        "From: $encFromName <$fromEmail>",
        "To: $to",
        "Subject: $encSubject",
        "MIME-Version: 1.0",
        "Content-Type: text/html; charset=UTF-8",
        "Content-Transfer-Encoding: base64",
        "Date: " . date('r'),
        "X-Mailer: ZeroTrust Shield",
        "",
        chunk_split(base64_encode($htmlBody)),
    ]);

    fwrite($sock, $msg . "\r\n.\r\n");
    $expect(250);

    $write("QUIT");
    fclose($sock);
    return true;
}
