<?php

namespace Velis\Mail;

use Psr\SimpleCache\InvalidArgumentException;
use Velis\App\Config;
use Velis\Bpm\Email\Account;
use Velis\Model\DataObject\NoColumnsException;
use Velis\Notification\Log;

/**
 * @author Damian Kurek <damian.kurek@velistech.com>
 */
class AccountFactory
{
    public const BACKUP_ACCOUNT_THRESHOLD = 3;

    protected Config $config;

    /**
     * @var Account
     */
    protected $account;

    /**
     * @var Log
     */
    protected $log;

    /**
     * @param Config $config
     * @param Account|int|null $account
     * @param Log|null $log
     * @throws InvalidArgumentException
     */
    public function __construct(Config $config, $account = null, $log = null)
    {
        $this->config = $config;
        if ($account && !$account instanceof Account) {
            $account = Account::get($account);
        }

        $this->account = $account;
        $this->log = $log;
    }


    /**
     * @return Account
     * @throws NoColumnsException
     */
    public function getAccount(): Account
    {
        if ($this->config['alwaysUseBackupServer'] && $this->config['smtpBackupServer']) {
            return $this->getBackupAccount();
        }

        if (
            $this->config['smtpBackupServer']
            && $this->log instanceof Log
            && $this->log->unsuccessful_attempts > self::BACKUP_ACCOUNT_THRESHOLD
        ) {
            return $this->getBackupAccount();
        }

        if ($this->account instanceof Account) {
            return $this->account;
        }

        return $this->getDefaultAccount();
    }


    /**
     * @return Account
     * @throws NoColumnsException
     */
    protected function getDefaultAccount(): Account
    {
        return new Account([
            'email_address' => $this->config['emailFrom'],
            'sender_label' => $this->config['nameFrom'],
            'outgoing_auth' => $this->config['smtpAuth'] ? : 'login',
            'login' => $this->config['smtpUser'],
            'password' => $this->config['smtpPassword'],
            'client_id' => $this->config['smtpClientId'],
            'client_secret' => $this->config['smtpClientSecret'] ?? $this->config['smtpPassword'],
            'outgoing_server' => $this->config['smtpServer'],
            'outgoing_port' => $this->config['smtpPort'] ?? 0,
            'outgoing_ssl' => $this->config['smtpSsl'] ?? 0,
        ]);
    }

    /**
     * @return Account
     * @throws NoColumnsException
     */
    protected function getBackupAccount(): Account
    {
        $account = $this->getDefaultAccount();
        $account->outgoing_server = $this->config['smtpBackupServer'];
        return $account;
    }
}
