<?php
namespace Misuzu;

use InvalidArgumentException;
use Misuzu\Config\IConfig;
use Symfony\Component\Mime\Email as SymfonyMessage;
use Symfony\Component\Mime\Address as SymfonyAddress;
use Symfony\Component\Mailer\Transport as SymfonyTransport;

final class Mailer {
    private const TEMPLATE_PATH = MSZ_ROOT . '/config/emails/%s.txt';

    private static IConfig $config;
    private static $transport = null;

    public static function init(IConfig $config): void {
        self::$config = $config;
    }

    private static function createDsn(): string {
        $config = self::$config->getValues([
            'method:s',
            'host:s',
            ['port:i', 25],
            'username:s',
            'password:s',
        ]);

        if($config['method'] !== 'smtp')
            return 'null://null';

        $dsn = $config['method'] . '://';

        if(!empty($config['username'])) {
            $dsn .= $config['username'];

            if(!empty($config['password']))
                $dsn .= ':' . $config['password'];

            $dsn .= '@';
        }

        $dsn .= $config['host'] ?? '';
        $dsn .= ':';
        $dsn .= $config['port'] ?? 25;

        return $dsn;
    }

    public static function getTransport() {
        if(self::$transport === null)
            self::$transport = SymfonyTransport::fromDsn(self::createDsn());
        return self::$transport;
    }

    public static function sendMessage(array $to, string $subject, string $contents, bool $bcc = false): bool {
        foreach($to as $email => $name) {
            $to = new SymfonyAddress($email, $name);
            break;
        }

        $config = self::$config->getValues([
            ['sender.name:s', 'Flashii'],
            ['sender.address:s', 'sys@flashii.net'],
        ]);

        $message = new SymfonyMessage;

        $message->from(new SymfonyAddress(
            $config['sender.address'],
            $config['sender.name']
        ));

        if($bcc)
            $message->bcc($to);
        else
            $message->to($to);

        $message->subject(trim($subject));
        $message->text(trim($contents));

        self::getTransport()->send($message);
        return true;
    }

    public static function template(string $name, array $vars = []): array {
        $path = sprintf(self::TEMPLATE_PATH, $name);

        if(!is_file($path))
            throw new InvalidArgumentException('Invalid e-mail template name.');

        $tpl = file_get_contents($path);

        // Normalise newlines
        $tpl = str_replace("\n", "\r\n", str_replace("\r\n", "\n", $tpl));

        foreach($vars as $key => $val)
            $tpl = str_replace("%{$key}%", $val, $tpl);

        [$subject, $message] = explode("\r\n\r\n", $tpl, 2);

        return compact('subject', 'message');
    }
}
