<?php
/**
 * Minimal SMTP client (socket-based) — no Composer/PHPMailer dependency,
 * works on any cPanel shared hosting with outbound SMTP allowed.
 * Reads live config from smtp_settings table (admin-controlled).
 */

require_once __DIR__ . '/../config/database.php';

class SimpleSmtpMailer
{
    private string $host;
    private int $port;
    private string $encryption; // SSL | TLS | NONE
    private string $username;
    private string $password;
    private string $senderName;
    private string $senderEmail;
    /** @var resource|false */
    private $socket;
    private array $log = [];

    public function __construct(array $config)
    {
        $this->host = $config['smtp_host'];
        $this->port = (int) $config['smtp_port'];
        $this->encryption = $config['smtp_encryption'] ?? 'SSL';
        $this->username = $config['smtp_username'];
        $this->password = $config['smtp_password'];
        $this->senderName = $config['sender_name'];
        $this->senderEmail = $config['sender_email'];
    }

    private function readResponse(): string
    {
        $data = '';
        while ($line = fgets($this->socket, 515)) {
            $data .= $line;
            if (isset($line[3]) && $line[3] === ' ') break;
        }
        $this->log[] = 'S: ' . trim($data);
        return $data;
    }

    private function sendCommand(string $command): string
    {
        $this->log[] = 'C: ' . preg_replace('/AUTH LOGIN.*|^[A-Za-z0-9+\/=]{10,}$/', '[hidden]', trim($command));
        fwrite($this->socket, $command . "\r\n");
        return $this->readResponse();
    }

    /**
     * @throws Exception on any SMTP failure — caller should catch and surface a clean message.
     */
    public function send(string $toEmail, string $toName, string $subject, string $htmlBody): bool
    {
        $transport = $this->encryption === 'SSL' ? 'ssl://' : '';
        $this->socket = @fsockopen($transport . $this->host, $this->port, $errno, $errstr, 15);

        if (!$this->socket) {
            throw new Exception("Could not connect to SMTP host: $errstr ($errno)");
        }

        $this->readResponse();
        $this->sendCommand('EHLO ' . $this->host);

        if ($this->encryption === 'TLS') {
            $this->sendCommand('STARTTLS');
            if (!stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
                throw new Exception('STARTTLS negotiation failed.');
            }
            $this->sendCommand('EHLO ' . $this->host);
        }

        $this->sendCommand('AUTH LOGIN');
        $this->sendCommand(base64_encode($this->username));
        $authResp = $this->sendCommand(base64_encode($this->password));
        if (!str_starts_with($authResp, '235')) {
            throw new Exception('SMTP authentication failed. Check username/password.');
        }

        $this->sendCommand('MAIL FROM:<' . $this->senderEmail . '>');
        $this->sendCommand('RCPT TO:<' . $toEmail . '>');
        $this->sendCommand('DATA');

        $boundary = uniqid('bnd_');
        $headers = [
            'From: ' . $this->senderName . ' <' . $this->senderEmail . '>',
            'To: ' . ($toName ?: $toEmail) . ' <' . $toEmail . '>',
            'Subject: ' . $subject,
            'MIME-Version: 1.0',
            'Content-Type: text/html; charset=UTF-8',
            'Date: ' . date('r'),
        ];

        $message = implode("\r\n", $headers) . "\r\n\r\n" . $htmlBody . "\r\n.";
        $dataResp = $this->sendCommand($message);

        $this->sendCommand('QUIT');
        fclose($this->socket);

        if (!str_starts_with($dataResp, '250')) {
            throw new Exception('Message not accepted by SMTP server.');
        }

        return true;
    }

    public function getLog(): array
    {
        return $this->log;
    }
}

/**
 * Convenience wrapper: loads active SMTP config from DB and sends one email.
 * Returns [success(bool), message(string)].
 */
function send_mail_via_settings(string $toEmail, string $toName, string $subject, string $htmlBody): array
{
    $pdo = getDbConnection();
    $stmt = $pdo->query('SELECT * FROM smtp_settings WHERE is_active = 1 LIMIT 1');
    $config = $stmt->fetch();

    if (!$config || empty($config['smtp_host']) || empty($config['smtp_username'])) {
        return [false, 'SMTP is not configured. Set it up in Admin Panel > SMTP.'];
    }

    try {
        $mailer = new SimpleSmtpMailer($config);
        $mailer->send($toEmail, $toName, $subject, $htmlBody);
        return [true, 'Email sent successfully.'];
    } catch (Throwable $e) {
        return [false, 'Failed to send email: ' . $e->getMessage()];
    }
}
