<?php

namespace App\Shared\Util;

use App\Shared\Constant\ErrorCodes;
use App\Shared\Exception\AppException;

/**
 * نام نمایشی پزشک/کلینیک در نتایج عمومی و در <title> صفحات سایت رندر می‌شود.
 * شماره‌تلفن یا «test» نام واقعی نیست و صفحه را بی‌ارزش می‌کند.
 *
 * این قواعد باید با nobat724_front/lib/entityQuality.js یکی بماند؛ سایت عمومی
 * همین رکوردها را noindex می‌کند. آنجا ماسک است، اینجا جلوگیری از تولید.
 */
final class DisplayName
{
    private const PHONE_LIKE = '/^0?9\d{9}$/';

    private const PLACEHOLDERS = ['test', 'تست', '-', '—', 'null', 'undefined'];

    private const MIN_LENGTH = 2;

    /** نامی که نباید در نتایج عمومی منتشر شود. */
    public static function isPlaceholder(?string $name): bool
    {
        $trimmed = trim((string) $name);
        if ($trimmed === '' || mb_strlen($trimmed) < self::MIN_LENGTH) {
            return true;
        }

        if (preg_match(self::PHONE_LIKE, str_replace([' ', '-', '‌'], '', $trimmed)) === 1) {
            return true;
        }

        return in_array(mb_strtolower($trimmed), self::PLACEHOLDERS, true);
    }

    /**
     * @throws AppException وقتی نام واقعی نباشد — ExceptionSubscriber آن را به 422 تبدیل می‌کند
     */
    public static function assertReal(?string $name): void
    {
        if (self::isPlaceholder($name)) {
            throw new AppException(
                ErrorCodes::ERR_VALIDATION_001,
                'نام معتبر نیست؛ شماره تلفن یا مقدار آزمایشی به‌عنوان نام پذیرفته نمی‌شود',
                422
            );
        }
    }
}
