<?php
// ============================================================
// app/mailer.php
// Helper SMTP puro (fsockopen) — sem dependências externas.
// Lê config de admin_smtp_settings (singleton id=1).
// ============================================================

require_once __DIR__ . '/db.php';

/**
 * Lê a config SMTP atual do banco.
 * Retorna null se não estiver habilitada ou estiver incompleta.
 */
function smtp_get_config(): ?array {
    try {
        $pdo = db();
        $stmt = $pdo->prepare("SELECT * FROM public.admin_smtp_settings WHERE id = 1 LIMIT 1");
        $stmt->execute();
        $cfg = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$cfg) return null;
        if (empty($cfg['enabled'])) return null;
        if (empty($cfg['smtp_host']) || empty($cfg['smtp_user']) || empty($cfg['smtp_pass']) || empty($cfg['mail_from'])) {
            return null;
        }
        return $cfg;
    } catch (Throwable $e) {
        return null;
    }
}

/**
 * Retorna o assunto configurado para o e-mail de "esqueci minha senha".
 * Fallback: "Defina sua senha".
 */
function smtp_get_subject_reset(): string {
    try {
        $pdo = db();
        $stmt = $pdo->prepare("SELECT mail_subject_reset FROM public.admin_smtp_settings WHERE id = 1");
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        $subject = trim($row['mail_subject_reset'] ?? '');
        return $subject !== '' ? $subject : 'Defina sua senha';
    } catch (Throwable $e) {
        return 'Defina sua senha';
    }
}

/**
 * Envia e-mail via SMTP autenticado usando fsockopen.
 */
function smtp_send(array $cfg, string $to, string $subject, string $html): array {
    $log = [];
    $host     = $cfg['smtp_host'] ?? '';
    $port     = (int)($cfg['smtp_port'] ?? 587);
    $secure   = strtolower($cfg['smtp_secure'] ?? 'tls');
    $user     = $cfg['smtp_user'] ?? '';
    $pass     = $cfg['smtp_pass'] ?? '';
    $from     = $cfg['mail_from'] ?? '';
    $fromName = $cfg['mail_from_name'] ?? '';

    if ($host === '' || $user === '' || $pass === '' || $from === '') {
        return ['ok'=>false, 'error'=>'Configuração SMTP incompleta', 'log'=>$log];
    }

    $remote = ($secure === 'ssl') ? "ssl://{$host}" : $host;
    $errno = 0; $errstr = '';
    $fp = @fsockopen($remote, $port, $errno, $errstr, 15);
    if (!$fp) {
        return ['ok'=>false, 'error'=>"Falha de conexão: {$errstr} ({$errno})", 'log'=>$log];
    }
    stream_set_timeout($fp, 15);

    $read = function() use ($fp, &$log) {
        $data = '';
        while ($line = fgets($fp, 515)) {
            $data .= $line;
            $log[] = '<- ' . rtrim($line);
            if (isset($line[3]) && $line[3] === ' ') break;
        }
        return $data;
    };
    $write = function(string $cmd, bool $hide=false) use ($fp, &$log) {
        $log[] = '-> ' . ($hide ? '[oculto]' : rtrim($cmd));
        fwrite($fp, $cmd . "\r\n");
    };
    $code = function(string $resp): int { return (int)substr($resp, 0, 3); };

    try {
        $resp = $read();
        if ($code($resp) !== 220) throw new RuntimeException('Banner inválido: ' . trim($resp));

        $hostname = $_SERVER['SERVER_NAME'] ?? 'localhost';
        $write("EHLO {$hostname}");
        $resp = $read();
        if ($code($resp) !== 250) throw new RuntimeException('EHLO falhou: ' . trim($resp));

        if ($secure === 'tls') {
            $write("STARTTLS");
            $resp = $read();
            if ($code($resp) !== 220) throw new RuntimeException('STARTTLS falhou: ' . trim($resp));
            if (!@stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT
                | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT)) {
                throw new RuntimeException('Falha ao habilitar TLS no socket');
            }
            $write("EHLO {$hostname}");
            $resp = $read();
            if ($code($resp) !== 250) throw new RuntimeException('EHLO pós-TLS falhou: ' . trim($resp));
        }

        $write("AUTH LOGIN");
        $resp = $read();
        if ($code($resp) !== 334) throw new RuntimeException('AUTH LOGIN falhou: ' . trim($resp));
        $write(base64_encode($user), true);
        $resp = $read();
        if ($code($resp) !== 334) throw new RuntimeException('Usuário rejeitado: ' . trim($resp));
        $write(base64_encode($pass), true);
        $resp = $read();
        if ($code($resp) !== 235) throw new RuntimeException('Autenticação falhou: ' . trim($resp));

        $write("MAIL FROM:<{$from}>");
        $resp = $read();
        if ($code($resp) !== 250) throw new RuntimeException('MAIL FROM falhou: ' . trim($resp));

        $write("RCPT TO:<{$to}>");
        $resp = $read();
        if (!in_array($code($resp), [250, 251], true)) throw new RuntimeException('RCPT TO falhou: ' . trim($resp));

        $write("DATA");
        $resp = $read();
        if ($code($resp) !== 354) throw new RuntimeException('DATA falhou: ' . trim($resp));

        $messageId = sprintf('<%s@%s>', bin2hex(random_bytes(8)), $host);
        $date = date('r');
        $fromHeader = $fromName !== ''
            ? '=?UTF-8?B?' . base64_encode($fromName) . '?= <' . $from . '>'
            : $from;

        $headers = [];
        $headers[] = "Date: {$date}";
        $headers[] = "From: {$fromHeader}";
        $headers[] = "To: <{$to}>";
        $headers[] = "Subject: =?UTF-8?B?" . base64_encode($subject) . "?=";
        $headers[] = "Message-ID: {$messageId}";
        $headers[] = "MIME-Version: 1.0";
        $headers[] = "Content-Type: text/html; charset=UTF-8";
        $headers[] = "Content-Transfer-Encoding: 8bit";

        $body = implode("\r\n", $headers) . "\r\n\r\n" . $html;
        $body = preg_replace('/^\./m', '..', $body);

        fwrite($fp, $body . "\r\n.\r\n");
        $resp = $read();
        if ($code($resp) !== 250) throw new RuntimeException('Envio recusado: ' . trim($resp));

        $write("QUIT");
        @fclose($fp);

        return ['ok'=>true, 'log'=>$log];

    } catch (Throwable $e) {
        @fclose($fp);
        return ['ok'=>false, 'error'=>$e->getMessage(), 'log'=>$log];
    }
}

/**
 * Função de alto nível: envia email do sistema.
 * Lê config automaticamente do banco. Faz fallback pra mail() nativo se SMTP não configurado.
 */
function send_system_email(string $to, string $subject, string $html): array {
    $cfg = smtp_get_config();
    if ($cfg !== null) {
        $res = smtp_send($cfg, $to, $subject, $html);
        $res['via'] = 'smtp';
        return $res;
    }

    // Fallback: mail() nativo (comportamento antigo)
    $from = 'suporte@evoluaprospect.com';
    $fromName = 'Evolua Prospect';
    $headers  = "From: {$fromName} <{$from}>\r\n";
    $headers .= "Reply-To: {$from}\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html; charset=UTF-8\r\n";
    $ok = @mail($to, $subject, $html, $headers);
    return ['ok'=>$ok, 'via'=>'mail', 'error'=>$ok ? null : 'mail() retornou false'];
}
