<?php

declare(strict_types=1);

namespace App\Framework\Email\Emails;

use App\Domain\Common\ValueObject\Email;
use App\Framework\Email\EmailContext;
use App\Framework\Email\EmailInterface;
use App\Framework\Email\EmailTemplateRenderer;
use App\Framework\Http\Url\Url;
use App\Framework\Http\Url\UrlFactory;
use App\Framework\Mail\EmailList;
use App\Framework\Mail\Message;
use App\Framework\Mail\Priority;

/**
 * Password reset email with security context
 */
final readonly class PasswordResetEmail implements EmailInterface
{
    public function __construct(
        public Email $to,
        public string $userName,
        public string $companyName,
        public Url $resetUrl,
        public string $resetCode,
        public string $requestIp,
        public int $expiryHours = 24,
        public Priority $priority = Priority::HIGHEST
    ) {
        if (empty(trim($userName))) {
            throw new \InvalidArgumentException('User name cannot be empty');
        }

        if (empty(trim($resetCode))) {
            throw new \InvalidArgumentException('Reset code cannot be empty');
        }

        if ($expiryHours <= 0 || $expiryHours > 72) {
            throw new \InvalidArgumentException('Expiry hours must be between 1 and 72');
        }
    }

    public function toMessage(EmailTemplateRenderer $renderer, Email $defaultFrom): Message
    {
        // Create template context
        $context = new EmailContext(
            data: [
                'name' => $this->userName,
                'company_name' => $this->companyName,
                'reset_url' => $this->resetUrl->toString(),
                'reset_code' => $this->resetCode,
                'request_ip' => $this->requestIp,
                'expiry_hours' => $this->expiryHours,
                'current_year' => date('Y'),
                'privacy_url' => '/privacy',
                'support_url' => '/support',
            ],
            preheader: "Passwort zurücksetzen - Aktion erforderlich"
        );

        // Render template
        $content = $renderer->render('password-reset', $context);

        // Create message
        return new Message(
            from: $defaultFrom,
            subject: $content->subject?->value ?? 'Passwort zurücksetzen - Aktion erforderlich',
            body: $content->text,
            htmlBody: $content->html,
            priority: $this->priority,
            to: new EmailList($this->to)
        );
    }

    /**
     * Factory method for simple creation
     */
    public static function for(
        Email|string $to,
        string $userName,
        string $companyName,
        Url|string $resetUrl,
        string $resetCode,
        string $requestIp,
        int $expiryHours = 24
    ): self {
        return new self(
            to: is_string($to) ? new Email($to) : $to,
            userName: $userName,
            companyName: $companyName,
            resetUrl: is_string($resetUrl) ? UrlFactory::parse($resetUrl) : $resetUrl,
            resetCode: $resetCode,
            requestIp: $requestIp,
            expiryHours: $expiryHours
        );
    }
}
