<?php

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

class CfMail
{
    private PHPMailer $mail;

    public function __construct(MailSettingsDTO $settings)
    {
        $this->mail = new PHPMailer(exceptions: true);
        if ($settings->isSmtpEnabled()) {
            $this->mail->isSMTP();
            $this->mail->Host = $settings->smtpHost;
            $this->mail->SMTPAuth = true;
            $this->mail->Username = $settings->smtpUser;
            $this->mail->Password = $settings->smtpPassword;
            $this->mail->SMTPSecure = $settings->smtpCrypto;
            $this->mail->Port = $settings->smtpPort;
            $this->mail->SMTPAutoTLS = false;
            // we don't ship ca-certificates.crt and not possible to verify peer
            $this->mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer' => false,
                )
            );
        } else {
            $this->mail->isSendmail();
            if (!empty($settings->mailPath)) {
                $this->mail->Sendmail = $settings->mailPath;
            }
        }
    }

    /**
     * @throws Exception
     */
    public function send(MailContentDTO $content): bool
    {

        if ($content->fromName) {
            $this->mail->setFrom($content->fromAddress, $content->fromName);
        } else {
            $this->mail->setFrom($content->fromAddress);
        }

        if (is_array($content->to)) {
            array_map(fn ($to) => $this->mail->addAddress($to), $content->to);
        } else {
            $this->mail->addAddress($content->to);
        }

        if ($content->replyTo) {
            $this->mail->addReplyTo($content->replyTo);
        }

        if ($content->cc) {
            $this->mail->addCC($content->cc);
        }

        if ($content->bcc) {
            $this->mail->addBCC($content->bcc);
        }

        if ($content->attachment) {
            $this->mail->addAttachment($content->attachment);
        }

        //Content
        $this->mail->isHTML($content->isHtmlBody);
        $this->mail->Subject = $content->subject;
        $this->mail->Body    = $content->body;
        if ($content->altBody) {
            $this->mail->AltBody = $content->altBody;
        }

        return $this->mail->send();
    }
}

readonly class MailContentDTO
{
    public function __construct(
        public string $fromAddress,
        public array|string $to,
        public string $subject,
        public string $body,
        public ?string $altBody = null, // plain text for non-HTML mail clients
        public ?string $cc = null,
        public ?string $bcc = null,
        public ?string $fromName = 'CFEngine hub',
        public ?string $attachment = null,
        public ?string $replyTo = null,
        public bool $isHtmlBody = false,
    ) {
    }
}
