<?php

namespace App\Services;

use App\Models\Setting;
use Illuminate\Support\Facades\Mail;

class MailService
{
    public function isConfigured(): bool
    {
        $host = Setting::get('mail_host');
        return ! empty($host);
    }

    public function getConfiguredMailer()
    {
        if (! $this->isConfigured()) {
            return null;
        }

        // '' = « Aucun » en admin (ex. Mailpit : 127.0.0.1:1025). Ne pas faire ?: 'tls' sur '' sinon TLS casse la connexion.
        $encryptionRaw = Setting::get('mail_encryption');
        if ($encryptionRaw === '') {
            $encryption = null;
        } elseif ($encryptionRaw === null) {
            $encryption = 'tls';
        } elseif (in_array($encryptionRaw, ['tls', 'ssl'], true)) {
            $encryption = $encryptionRaw;
        } else {
            $encryption = 'tls';
        }

        $username = Setting::get('mail_username');
        $password = Setting::get('mail_password');
        $username = ($username !== null && $username !== '') ? $username : null;
        $password = ($password !== null && $password !== '') ? $password : null;

        $config = [
            'transport' => 'smtp',
            'host' => Setting::get('mail_host', ''),
            'port' => (int) (Setting::get('mail_port') ?: 587),
            'encryption' => $encryption,
            'username' => $username,
            'password' => $password,
            'timeout' => 30,
        ];

        return Mail::build($config);
    }

    public function send($mailable): bool
    {
        $mailer = $this->getConfiguredMailer();
        if (! $mailer) {
            return false;
        }

        try {
            $mailer->send($mailable);
            return true;
        } catch (\Throwable $e) {
            report($e);
            return false;
        }
    }

    public function getFromAddress(): array
    {
        $address = Setting::get('mail_from_address') ?: config('mail.from.address', 'noreply@example.com');
        $name = Setting::get('mail_from_name') ?: config('mail.from.name', config('app.name'));

        return ['address' => $address, 'name' => $name];
    }

    public function getAdminEmails(): array
    {
        $emails = Setting::get('mail_admin_email', '');
        if (empty($emails)) {
            return [];
        }

        return array_filter(array_map('trim', explode(',', $emails)));
    }

    /**
     * Destinataires des alertes (contact, commande, réservation).
     * Si « E-mails administrateur » est vide, repli sur l’e-mail expéditeur (From) s’il est valide.
     */
    public function getNotificationRecipientEmails(): array
    {
        $admins = $this->getAdminEmails();
        if ($admins !== []) {
            return array_values($admins);
        }

        $from = Setting::get('mail_from_address');
        if (is_string($from) && $from !== '' && self::isPlausibleEmailAddress($from)) {
            return [$from];
        }

        return [];
    }

    /**
     * filter_var rejette parfois les adresses locales (ex. test@localhost pour Mailpit).
     */
    private static function isPlausibleEmailAddress(string $address): bool
    {
        if (filter_var($address, FILTER_VALIDATE_EMAIL)) {
            return true;
        }

        return (bool) preg_match('/^[^@\s]+@[^@\s]+$/', $address);
    }
}
