<?php
require_once __DIR__ . '/db.php';

/**
 * Reads multi-line response from SMTP socket
 */
if (!function_exists('read_smtp_response')) {
    function read_smtp_response($socket) {
        $response = "";
        $startTime = time();
        while ($line = fgets($socket, 512)) {
            $response .= $line;
            // Check for RFC 5321 multiline format (3 digits followed by a space)
            if (strlen($line) >= 4 && $line[3] === ' ') {
                break;
            }
            // Protect against hanging
            if (time() - $startTime > 10) {
                break;
            }
        }
        return $response;
    }
}

/**
 * Sends a command to the socket and returns response
 */
if (!function_exists('send_smtp_command')) {
    function send_smtp_command($socket, $command, $expected_code) {
        fwrite($socket, $command . "\r\n");
        $response = read_smtp_response($socket);
        $code = substr(trim($response), 0, 3);
        if ($code !== $expected_code) {
            throw new Exception("SMTP Error: Command '" . trim($command) . "' failed. Expected status code $expected_code but got response: " . trim($response));
        }
        return $response;
    }
}

/**
 * Sends an email using SMTP connection details
 */
if (!function_exists('send_smtp_email')) {
    function send_smtp_email($to, $subject, $body_html, $from_email, $from_name, $smtp) {
        $host = $smtp['smtp_host'] ?? '';
        $port = (int)($smtp['smtp_port'] ?? 465);
        $username = $smtp['smtp_username'] ?? '';
        $password = $smtp['smtp_password'] ?? '';

        // Secure SSL transport for port 465 (or if host specifies it)
        $socket_host = $host;
        if (($port === 465 || strpos($host, 'mail.') !== false) && strpos($host, 'ssl://') === false && strpos($host, 'tls://') === false) {
            $socket_host = 'ssl://' . $host;
        }

        $socket = @fsockopen($socket_host, $port, $errno, $errstr, 15);
        if (!$socket) {
            throw new Exception("SMTP Connection Failed: $errstr ($errno) - Host: $socket_host, Port: $port");
        }

        try {
            // Set timeout
            stream_set_timeout($socket, 15);

            // Read Greeting
            $greeting = read_smtp_response($socket);
            $code = substr(trim($greeting), 0, 3);
            if ($code !== '220') {
                throw new Exception("SMTP Greeting failed: $greeting");
            }

            // EHLO
            send_smtp_command($socket, "EHLO localhost", "250");

            // AUTH LOGIN
            send_smtp_command($socket, "AUTH LOGIN", "334");

            // Username
            send_smtp_command($socket, base64_encode($username), "334");

            // Password
            send_smtp_command($socket, base64_encode($password), "235");

            // MAIL FROM
            send_smtp_command($socket, "MAIL FROM:<$from_email>", "250");

            // RCPT TO
            send_smtp_command($socket, "RCPT TO:<$to>", "250");

            // DATA
            send_smtp_command($socket, "DATA", "354");

            // Headers and Message Body
            $headers = [
                "MIME-Version: 1.0",
                "Content-Type: text/html; charset=UTF-8",
                "Content-Transfer-Encoding: base64",
                "From: " . ($from_name ? "\"$from_name\" <$from_email>" : $from_email),
                "To: <$to>",
                "Subject: =?UTF-8?B?" . base64_encode($subject) . "?=",
                "Date: " . date('r'),
                "Message-ID: <" . time() . "-" . uniqid() . "@" . (str_replace(['ssl://', 'tls://'], '', $host) ?: 'localhost') . ">",
                "X-Mailer: NexCore SMTP Client"
            ];

            // Encode HTML body as Base64 and chunk to 76 characters per line
            $msg_body = chunk_split(base64_encode($body_html), 76, "\r\n");
            
            // SMTP message structure: headers, empty line, body
            $raw_message = implode("\r\n", $headers) . "\r\n\r\n" . $msg_body;

            // Send raw message followed by dot
            fwrite($socket, $raw_message . ".\r\n");
            
            $response = read_smtp_response($socket);
            $code = substr(trim($response), 0, 3);
            if ($code !== '250') {
                throw new Exception("SMTP DATA send failed: $response");
            }

            // QUIT
            fwrite($socket, "QUIT\r\n");
            read_smtp_response($socket);

        } catch (Exception $e) {
            @fwrite($socket, "QUIT\r\n");
            @fclose($socket);
            throw $e;
        }

        @fclose($socket);
        return true;
    }
}
