<?php

declare(strict_types=1);

namespace App\Framework\Mail\Examples;

use App\Domain\Common\ValueObject\Email;
use App\Framework\Mail\Attachment;
use App\Framework\Mail\EmailList;
use App\Framework\Mail\Mailer;
use App\Framework\Mail\Message;
use App\Framework\Mail\Priority;

/**
 * Example usage of the Mailer system with queue integration
 *
 * This class demonstrates how to use the mailer for different scenarios:
 * - Single email sending (sync)
 * - Queue-based sending (async)
 * - Batch operations
 * - Different retry strategies
 */
final readonly class MailerUsageExample
{
    public function __construct(
        private Mailer $mailer,
    ) {
    }

    /**
     * Send a simple transactional email immediately
     */
    public function sendWelcomeEmail(Email $userEmail, string $userName): bool
    {
        $message = new Message(
            from: new Email('noreply@example.com'),
            subject: 'Welcome to our service!',
            body: "Hello {$userName},\n\nWelcome to our service!",
            htmlBody: "<h1>Hello {$userName}</h1><p>Welcome to our service!</p>",
            to: new EmailList([$userEmail]),
        );

        // Send immediately (synchronous)
        return $this->mailer->send($message);
    }

    /**
     * Queue a password reset email with custom retry settings
     */
    public function queuePasswordResetEmail(Email $userEmail, string $resetToken): bool
    {
        $message = new Message(
            from: new Email('security@example.com'),
            subject: 'Password Reset Request',
            body: "Please use this token to reset your password: {$resetToken}",
            htmlBody: "<p>Please use this token to reset your password:</p><code>{$resetToken}</code>",
            to: new EmailList([$userEmail]),
            priority: Priority::HIGH,
        );

        // Queue with higher retry count for important emails
        return $this->mailer->queue($message, maxRetries: 5, delaySeconds: 30);
    }

    /**
     * Send newsletter to multiple recipients using batch queue
     */
    public function sendNewsletter(array $subscribers, string $subject, string $content): array
    {
        $messages = [];

        foreach ($subscribers as $subscriber) {
            $messages[] = new Message(
                from: new Email('newsletter@example.com'),
                subject: $subject,
                body: strip_tags($content),
                htmlBody: $content,
                to: new EmailList([new Email($subscriber['email'])]),
                priority: Priority::LOW,
            );
        }

        // Use batch queue for better performance
        return $this->mailer->queueBatch($messages, maxRetries: 2, delaySeconds: 60);
    }

    /**
     * Send email with attachment
     */
    public function sendInvoiceEmail(Email $customerEmail, string $invoicePath): bool
    {
        $attachment = Attachment::fromFile(
            storage: app()->get('storage'), // Assuming storage is available via DI
            filePath: $invoicePath,
            name: 'invoice.pdf'
        );

        $message = new Message(
            from: new Email('billing@example.com'),
            subject: 'Your Invoice',
            body: 'Please find your invoice attached.',
            htmlBody: '<p>Please find your invoice attached.</p>',
            to: new EmailList([$customerEmail]),
            attachments: [$attachment],
            priority: Priority::NORMAL,
        );

        // Send with moderate retry settings
        return $this->mailer->queue($message, maxRetries: 3, delaySeconds: 0);
    }

    /**
     * Send notification email with CC and BCC
     */
    public function sendNotificationEmail(
        Email $primaryRecipient,
        array $ccEmails = [],
        array $bccEmails = [],
        string $subject = 'System Notification',
        string $message = 'This is a system notification.'
    ): bool {
        $email = new Message(
            from: new Email('system@example.com'),
            subject: $subject,
            body: $message,
            htmlBody: "<p>{$message}</p>",
            to: new EmailList([$primaryRecipient]),
            cc: new EmailList(array_map(fn ($email) => new Email($email), $ccEmails)),
            bcc: new EmailList(array_map(fn ($email) => new Email($email), $bccEmails)),
            replyTo: new Email('support@example.com'),
        );

        return $this->mailer->send($email);
    }

    /**
     * Example of error handling when sending fails
     */
    public function sendWithErrorHandling(Email $recipient, string $subject, string $content): string
    {
        $message = new Message(
            from: new Email('noreply@example.com'),
            subject: $subject,
            body: $content,
            to: new EmailList([$recipient]),
        );

        try {
            $success = $this->mailer->send($message);

            if ($success) {
                return "Email sent successfully to {$recipient->value}";
            } else {
                return "Failed to send email to {$recipient->value}";
            }

        } catch (\Exception $e) {
            // Log the error (assuming logger is available)
            error_log("Email sending failed: " . $e->getMessage());

            return "Email sending failed with error: " . $e->getMessage();
        }
    }
}
