<?php
declare(strict_types=1);

namespace App\Framework\Validation\Rules;

use App\Framework\Validation\ValidationRule;
use Attribute;

#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER)]
final readonly class StringLength implements ValidationRule
{
    /**
     * @param int|null $min Minimale Länge des Strings
     * @param int|null $max Maximale Länge des Strings
     * @param string|null $message Benutzerdefinierte Fehlermeldung
     */
    public function __construct(
        private ?int    $min = null,
        private ?int    $max = null,
        private ?string $message = null
    ) {
        if ($min === null && $max === null) {
            throw new \InvalidArgumentException('Mindestens einer der Parameter min oder max muss gesetzt sein.');
        }
    }

    public function validate(mixed $value): bool
    {
        if ($value === null || $value === '') {
            return true; // Leere Werte werden von Required-Regel behandelt
        }

        if (!is_string($value)) {
            return false;
        }

        $length = mb_strlen($value);

        if ($this->min !== null && $length < $this->min) {
            return false;
        }

        if ($this->max !== null && $length > $this->max) {
            return false;
        }

        return true;
    }

    public function getErrorMessages(): array
    {
        if ($this->message !== null) {
            return [$this->message];
        }

        if ($this->min !== null && $this->max !== null) {
            return ["Dieser Wert muss zwischen {$this->min} und {$this->max} Zeichen lang sein."];
        } elseif ($this->min !== null) {
            return ["Dieser Wert muss mindestens {$this->min} Zeichen lang sein."];
        } else {
            return ["Dieser Wert darf maximal {$this->max} Zeichen lang sein."];
        }
    }
}
