<?php

declare(strict_types=1);

namespace App\Framework\Mail;

use InvalidArgumentException;

final readonly class SmtpConfig
{
    public function __construct(
        public string $host,
        public int $port = 587,
        public string $username = '',
        public string $password = '',
        public SmtpEncryption $encryption = SmtpEncryption::None,
        public int $timeout = 30,
        public bool $authentication = true,
        public bool $verifyPeer = true,
    ) {
        if ($port < 1 || $port > 65535) {
            throw new InvalidArgumentException('Port must be between 1 and 65535');
        }

        if ($timeout < 1) {
            throw new InvalidArgumentException('Timeout must be positive');
        }
    }

    public static function createTls(string $host, int $port, string $username, string $password): self
    {
        return new self(
            host: $host,
            port: $port,
            username: $username,
            password: $password,
            encryption: SmtpEncryption::TLS,
        );
    }

    public static function createSsl(string $host, int $port, string $username, string $password): self
    {
        return new self(
            host: $host,
            port: $port,
            username: $username,
            password: $password,
            encryption: SmtpEncryption::SSL,
        );
    }

    public static function createPlain(string $host, int $port, string $username = '', string $password = ''): self
    {
        return new self(
            host: $host,
            port: $port,
            username: $username,
            password: $password,
            encryption: SmtpEncryption::None,
            authentication: ! empty($username),
        );
    }

    public function requiresAuthentication(): bool
    {
        return $this->authentication && ! empty($this->username);
    }

    public function hasEncryption(): bool
    {
        return $this->encryption !== SmtpEncryption::None;
    }

    public function getConnectionString(): string
    {
        if ($this->hasEncryption()) {
            return $this->encryption->value . '://' . $this->host . ':' . $this->port;
        }

        return $this->host . ':' . $this->port;
    }
}
