<?php

namespace Core\System;

class Mailer
{
    protected array $settings = [];

    public function __construct()
    {
        $this->loadSettings();
    }

     protected function loadSettings(): void
    {
        if (!function_exists('db')) {
            return;
        }

        try {
            $stmt = db()->query("SELECT setting_key, setting_value FROM settings");
            $this->settings = $stmt->fetchAll(\PDO::FETCH_KEY_PAIR);
        } catch (\Throwable $e) {
            $this->settings = [];
        }
    }

  
    public function send(string $to, string $subject, string $body): bool
    {
        $driver = $this->settings['mail_driver'] ?? 'mail';

        if ($driver === 'smtp') {
            return $this->sendSMTP($to, $subject, $body);
        }

        return $this->sendMail($to, $subject, $body);
    }

    /**
     * Sanitize a string for use in email headers (prevent header injection).
     */
    private function sanitizeHeader(string $value): string
    {
        return str_replace(["\r", "\n", "\0"], '', $value);
    }

    /**
     * إرسال باستخدام PHP mail()
     */
    protected function sendMail(string $to, string $subject, string $body): bool
    {
        $fromEmail = $this->sanitizeHeader($this->settings['mail_from_email'] ?? 'no-reply@localhost');
        $fromName  = $this->sanitizeHeader($this->settings['mail_from_name']  ?? 'MTEngine');
        $to        = $this->sanitizeHeader($to);
        $subject   = $this->sanitizeHeader($subject);

        $headers   = [];
        $headers[] = "MIME-Version: 1.0";
        $headers[] = "Content-type:text/html;charset=UTF-8";
        $headers[] = "From: {$fromName} <{$fromEmail}>";

        return @mail($to, $subject, $body, implode("\r\n", $headers));
    }

    /**
     * إرسال باستخدام SMTP (بدون مكتبات خارجية)
     */
    protected function sendSMTP(string $to, string $subject, string $body): bool
    {
        $host = $this->settings['mail_host'] ?? '';
        $port = (int)($this->settings['mail_port'] ?? 25);
        $user = $this->settings['mail_username'] ?? '';
        $pass = $this->settings['mail_password'] ?? '';
        $enc  = $this->settings['mail_encryption'] ?? 'none';

        $fromEmail = $this->sanitizeHeader($this->settings['mail_from_email'] ?? 'no-reply@localhost');
        $fromName  = $this->sanitizeHeader($this->settings['mail_from_name']  ?? 'MTEngine');
        $to        = $this->sanitizeHeader($to);

        if ($host === '' || $user === '' || $pass === '') {
            return false;
        }

        $remote = ($enc === 'ssl' ? 'ssl://' : '') . $host;

        $fp = @fsockopen($remote, $port, $errno, $errstr, 10);
        if (!$fp) {
            return false;
        }

        $this->read($fp);
        $this->write($fp, "EHLO {$host}");
        $this->read($fp);

        if ($enc === 'tls') {
            $this->write($fp, "STARTTLS");
            $this->read($fp);
            stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
            $this->write($fp, "EHLO {$host}");
            $this->read($fp);
        }

        $this->write($fp, "AUTH LOGIN");
        $this->read($fp);
        $this->write($fp, base64_encode($user));
        $this->read($fp);
        $this->write($fp, base64_encode($pass));
        $this->read($fp);

        $this->write($fp, "MAIL FROM:<{$fromEmail}>");
        $this->read($fp);
        $this->write($fp, "RCPT TO:<{$to}>");
        $this->read($fp);
        $this->write($fp, "DATA");
        $this->read($fp);

        $headers  = "From: {$fromName} <{$fromEmail}>\r\n";
        $headers .= "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: text/html; charset=UTF-8\r\n";

        $message  = $headers . "\r\n" . $body;

        $this->write($fp, $message . "\r\n.");
        $this->read($fp);

        $this->write($fp, "QUIT");
        fclose($fp);

        return true;
    }

    protected function write($fp, string $data): void
    {
        fwrite($fp, $data . "\r\n");
    }

    protected function read($fp): string
    {
        $data = '';
        while ($str = fgets($fp, 515)) {
            $data .= $str;
            if (substr($str, 3, 1) === ' ') {
                break;
            }
        }
        return $data;
    }
}
