<?php
declare(strict_types=1);

namespace App\Application\Security\Events\Input;

use App\Application\Security\{OWASPSecurityEvent};
use App\Application\Security\ValueObjects\{OWASPEventIdentifier, OWASPLogLevel, MaskedEmail};

final class InputValidationFailureEvent implements OWASPSecurityEvent
{
    private ?MaskedEmail $maskedEmail;

    public function __construct(
        public readonly string $fieldName,
        public readonly string $invalidValue,
        public readonly string $validationRule,
        public readonly ?string $email = null
    ) {
        $this->maskedEmail = $this->email ? MaskedEmail::fromString($this->email) : null;
    }

    public function getOWASPEventIdentifier(): OWASPEventIdentifier
    {
        return OWASPEventIdentifier::inputValidationFailure($this->fieldName);
    }

    public function getOWASPLogLevel(): OWASPLogLevel
    {
        return OWASPLogLevel::WARN;
    }

    public function getDescription(): string
    {
        return "Input validation failure for field {$this->fieldName}";
    }

    public function getEventData(): array
    {
        return [
            'field_name' => $this->fieldName,
            'invalid_value' => $this->sanitizeForLog($this->invalidValue),
            'validation_rule' => $this->validationRule,
            'username' => $this->maskedEmail?->toString() ?? 'anonymous'
        ];
    }

    public function getMaskedEmail(): ?MaskedEmail
    {
        return $this->maskedEmail;
    }

    private function sanitizeForLog(string $value): string
    {
        // Maximal 100 Zeichen und gefährliche Zeichen entfernen
        $sanitized = substr($value, 0, 100);
        return preg_replace('/[^\w\s\.\-@]/', '***', $sanitized);
    }
}
