<?php
/**
 * Transactional email sender.
 *
 * Config lives in sp_settings (keyval='email', group='email', encrypted=1):
 *   { "provider":"brevo", "api_key":<encrypted>, "from_email":"...", "from_name":"..." }
 * Seed it with db/seed_email.php (reads BREVO_API_KEY from the environment).
 *
 * Send order: Brevo HTTP API (if configured) → SMTP via config.php EMAIL* constants
 * (if set) → false. Callers treat false as "not sent" and log a fallback (e.g. the
 * account verification link) so flows stay testable before email is wired up.
 */
class Mailer
{
    /** @return bool true when the provider accepted the message. */
    public static function send(string $toEmail, string $toName, string $subject, string $html, string $text = ''): bool
    {
        $cfg = json_decode((string) \Db::getValue(
            "SELECT metval FROM sp_settings WHERE keyval = 'email' AND status = 1 LIMIT 1"
        ), true) ?: [];

        if (strtolower((string) ($cfg['provider'] ?? '')) === 'brevo' && !empty($cfg['api_key'])) {
            return self::sendBrevo($cfg, $toEmail, $toName, $subject, $html, $text);
        }

        $host = defined('EMAILHOST') ? (string) EMAILHOST : '';
        if ($host !== '' && !str_starts_with($host, 'ADD')) {
            return self::sendSmtp($toEmail, $toName, $subject, $html, $text);
        }

        return false; // unconfigured
    }

    private static function fromEmail(array $cfg): string
    {
        $from = trim((string) ($cfg['from_email'] ?? ''));
        return $from !== '' ? $from : 'noreply@' . (parse_url(URL, PHP_URL_HOST) ?: 'localhost');
    }

    private static function fromName(array $cfg): string
    {
        $name = trim((string) ($cfg['from_name'] ?? ''));
        return $name !== '' ? $name : (defined('PROJECT_NAME') ? PROJECT_NAME : 'Website');
    }

    private static function sendBrevo(array $cfg, string $toEmail, string $toName, string $subject, string $html, string $text): bool
    {
        try {
            $http = new \GuzzleHttp\Client(['timeout' => 12, 'http_errors' => false]);
            $res = $http->post('https://api.brevo.com/v3/smtp/email', [
                'headers' => [
                    'api-key'      => \Functions::Decrypt((string) $cfg['api_key']),
                    'accept'       => 'application/json',
                    'content-type' => 'application/json',
                ],
                'json' => [
                    'sender'      => ['name' => self::fromName($cfg), 'email' => self::fromEmail($cfg)],
                    'to'          => [['email' => $toEmail, 'name' => $toName !== '' ? $toName : $toEmail]],
                    'subject'     => $subject,
                    'htmlContent' => $html,
                    'textContent' => $text !== '' ? $text : trim(strip_tags($html)),
                ],
            ]);
            $code = $res->getStatusCode();
            if ($code >= 200 && $code < 300) {
                return true;
            }
            error_log('[mailer] brevo HTTP ' . $code . ': ' . (string) $res->getBody());
            return false;
        } catch (\Throwable $e) {
            error_log('[mailer] brevo exception: ' . $e->getMessage());
            return false;
        }
    }

    private static function sendSmtp(string $toEmail, string $toName, string $subject, string $html, string $text): bool
    {
        try {
            $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
            $mail->isSMTP();
            $mail->Host       = EMAILHOST;
            $mail->SMTPAuth   = true;
            $mail->Username   = defined('EMAILUSER') ? EMAILUSER : '';
            $mail->Password   = defined('EMAILPASSWORD') ? EMAILPASSWORD : '';
            $mail->SMTPSecure = 'tls';
            $mail->Port       = 587;
            $mail->setFrom('noreply@' . (parse_url(URL, PHP_URL_HOST) ?: 'localhost'), defined('PROJECT_NAME') ? PROJECT_NAME : 'Website');
            $mail->addAddress($toEmail, $toName !== '' ? $toName : $toEmail);
            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body    = $html;
            $mail->AltBody = $text !== '' ? $text : trim(strip_tags($html));
            $mail->send();
            return true;
        } catch (\Throwable $e) {
            error_log('[mailer] smtp send failed: ' . $e->getMessage());
            return false;
        }
    }
}
