<?php

declare(strict_types=1);

final class MyronMailSettingsRepository
{
    public function __construct(
        private readonly PDO $pdo,
    ) {
    }

    public function getSettings(): ?array
    {
        $statement = $this->pdo->query('SELECT * FROM mail_settings WHERE id = 1 LIMIT 1');
        $row = $statement->fetch();
        if (!is_array($row)) {
            return null;
        }

        $row['smtp_password'] = myronAppKeyAvailable()
            ? myronDecryptSecret((string) ($row['smtp_password_encrypted'] ?? ''))
            : '';
        $row['password_mask'] = myronMaskSecret((string) ($row['smtp_password_encrypted'] ?? ''));
        return $row;
    }

    public function isConfigured(): bool
    {
        $settings = $this->getSettings();
        return is_array($settings)
            && myronAppKeyAvailable()
            && trim((string) ($settings['smtp_password'] ?? '')) !== '';
    }

    public function saveSettings(array $input): void
    {
        if (!myronAppKeyAvailable()) {
            throw new RuntimeException('MYRON_APP_KEY must be configured before mail credentials can be saved.');
        }

        $host = trim((string) ($input['smtp_host'] ?? ''));
        $port = (int) ($input['smtp_port'] ?? 587);
        $security = strtolower(trim((string) ($input['smtp_security'] ?? 'tls')));
        $username = trim((string) ($input['smtp_username'] ?? ''));
        $password = (string) ($input['smtp_password'] ?? '');
        $fromEmail = myronNormalizeEmail((string) ($input['from_email'] ?? ''));
        $fromName = trim((string) ($input['from_name'] ?? ''));

        if ($host === '') {
            throw new InvalidArgumentException('SMTP host is required.');
        }

        if ($port < 1 || $port > 65535) {
            throw new InvalidArgumentException('SMTP port must be between 1 and 65535.');
        }

        if (!in_array($security, ['none', 'ssl', 'tls'], true)) {
            throw new InvalidArgumentException('SMTP security must be none, ssl, or tls.');
        }

        if ($username === '') {
            throw new InvalidArgumentException('SMTP username is required.');
        }

        if (!filter_var($fromEmail, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException('A valid sender email address is required.');
        }
        if (!$this->senderDomainMatchesInstallDomain($fromEmail)) {
            throw new InvalidArgumentException('From Email must use the install domain or one of its subdomains.');
        }

        if ($fromName === '') {
            throw new InvalidArgumentException('Sender name is required.');
        }

        $existing = $this->getSettings();
        if ($password === '' && !is_array($existing)) {
            throw new InvalidArgumentException('SMTP password is required.');
        }

        $encryptedPassword = $password !== ''
            ? myronEncryptSecret($password)
            : (string) ($existing['smtp_password_encrypted'] ?? '');

        $statement = $this->pdo->prepare(
            'REPLACE INTO mail_settings (
                id, smtp_host, smtp_port, smtp_security, smtp_username, smtp_password_encrypted, from_email, from_name, updated_at
             ) VALUES (
                1, :smtp_host, :smtp_port, :smtp_security, :smtp_username, :smtp_password_encrypted, :from_email, :from_name, :updated_at
             )'
        );
        $statement->execute([
            ':smtp_host' => $host,
            ':smtp_port' => $port,
            ':smtp_security' => $security,
            ':smtp_username' => $username,
            ':smtp_password_encrypted' => $encryptedPassword,
            ':from_email' => $fromEmail,
            ':from_name' => $fromName,
            ':updated_at' => myronNow(),
        ]);
    }

    public function senderDomainMatchesInstallDomain(string $email): bool
    {
        $parts = explode('@', myronNormalizeEmail($email), 2);
        $senderDomain = $parts[1] ?? '';
        $installHost = strtolower((string) parse_url(myronAppUrl(), PHP_URL_HOST));
        if ($senderDomain === '' || $installHost === '') {
            return true;
        }
        if ($installHost === 'localhost' || !str_contains($installHost, '.') || filter_var($installHost, FILTER_VALIDATE_IP)) {
            return true;
        }
        return $senderDomain === $installHost || str_ends_with($senderDomain, '.' . $installHost);
    }
}
