<?php

declare(strict_types=1);

namespace Autogedal\AwbRetry\Model;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Validator\EmailAddress;
use Magento\Store\Model\ScopeInterface;
class Config
{
    private const XML_PATH_MAX_ATTEMPTS = 'autogedal_awb_retry/retry/max_attempts';
    private const XML_PATH_RETRY_DELAY_MS = 'autogedal_awb_retry/retry/retry_delay_ms';
    private const XML_PATH_TRANSIENT_FAILURE_PATTERNS = 'autogedal_awb_retry/retry/transient_failure_patterns';
    private const XML_PATH_EMAIL_TEMPLATE = 'autogedal_awb_retry/email/template';
    private const XML_PATH_EMAIL_TO = 'autogedal_awb_retry/email/to';
    private const DEFAULT_TRANSIENT_FAILURE_PATTERNS = [
        'timed out',
        'timeout',
        'operation timed out',
        'curl error',
        'connection refused',
        'connection reset',
        'gateway timeout',
        'temporarily unavailable',
        'service unavailable',
        'bad gateway',
        'http error 502',
        'http error 503',
        'http error 504',
    ];

    public function __construct(
        private readonly ScopeConfigInterface $scopeConfig,
        private readonly EmailAddress $emailAddressValidator
    ) {
    }

    public function getMaxAttempts(): int
    {
        return max(1, (int) $this->scopeConfig->getValue(self::XML_PATH_MAX_ATTEMPTS, ScopeInterface::SCOPE_STORE));
    }

    public function getRetryDelayMs(): int
    {
        return max(0, (int) $this->scopeConfig->getValue(self::XML_PATH_RETRY_DELAY_MS, ScopeInterface::SCOPE_STORE));
    }

    /**
     * @return string[]
     */
    public function getTransientFailurePatterns(): array
    {
        $rawValue = trim((string) $this->scopeConfig->getValue(
            self::XML_PATH_TRANSIENT_FAILURE_PATTERNS,
            ScopeInterface::SCOPE_STORE
        ));

        if ($rawValue === '') {
            return self::DEFAULT_TRANSIENT_FAILURE_PATTERNS;
        }

        $patterns = preg_split('/[\r\n,;]+/', $rawValue) ?: [];
        $patterns = array_map('trim', $patterns);
        $patterns = array_filter($patterns, static fn (string $pattern): bool => $pattern !== '');

        return array_values($patterns);
    }

    public function getFailureEmailTemplate(): string
    {
        return trim((string) $this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, ScopeInterface::SCOPE_STORE));
    }

    /**
     * @return string[]
     */
    public function getFailureEmailRecipients(): array
    {
        $rawValue = trim((string) $this->scopeConfig->getValue(self::XML_PATH_EMAIL_TO, ScopeInterface::SCOPE_STORE));
        if ($rawValue === '') {
            return [];
        }

        $recipients = preg_split('/[\s,;]+/', $rawValue) ?: [];
        $recipients = array_map('trim', $recipients);
        $recipients = array_filter($recipients, static fn (string $email): bool => $email !== '');

        return array_values(array_filter(
            $recipients,
            fn (string $email): bool => $this->emailAddressValidator->isValid($email)
        ));
    }
}
