<?php

namespace App\Tests\Shared;

use App\Shared\Exception\AppException;
use App\Shared\Util\DisplayName;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

/**
 * These rules must stay in sync with nobat724_front/lib/entityQuality.js — the
 * public site noindexes exactly the records this class refuses to create.
 */
class DisplayNameTest extends TestCase
{
    /** @return array<string, array{string}> */
    public static function pollutedNames(): array
    {
        return [
            'mobile'                 => ['09390039833'],
            'mobile without leading' => ['9390039833'],
            'mobile with spaces'     => ['0939 003 9833'],
            'mobile with dashes'     => ['0939-003-9833'],
            'test latin'             => ['test'],
            'test latin uppercase'   => ['TEST'],
            'test persian'           => ['تست'],
            'dash'                   => ['-'],
            'empty'                  => [''],
            'whitespace only'        => ['   '],
            'single char'            => ['a'],
            'literal null'           => ['null'],
        ];
    }

    #[DataProvider('pollutedNames')]
    public function testPollutedNamesAreRejected(string $name): void
    {
        // «{$name}» — بدون آکولاد، PHP کاراکتر » را جزو نام متغیر می‌گیرد
        $this->assertTrue(DisplayName::isPlaceholder($name), "«{$name}» باید نامعتبر باشد");

        $this->expectException(AppException::class);
        DisplayName::assertReal($name);
    }

    /** @return array<string, array{string}> */
    public static function realNames(): array
    {
        return [
            'persian full name' => ['سیده مهدیه کشاورز'],
            'with title'        => ['دکتر علی احمدی'],
            'clinic name'       => ['کلینیک تخصصی امید تبریز'],
            'short persian'     => ['رضا'],
            'latin name'        => ['John Smith'],
            // شماره‌ای که الگوی موبایل ایران نیست، نام عجیبی است ولی سانسور نمی‌شود
            'landline'          => ['02191550875'],
        ];
    }

    #[DataProvider('realNames')]
    public function testRealNamesPass(string $name): void
    {
        $this->assertFalse(DisplayName::isPlaceholder($name), "«{$name}» باید معتبر باشد");

        DisplayName::assertReal($name);
        $this->addToAssertionCount(1);
    }

    public function testNullIsTreatedAsPlaceholder(): void
    {
        $this->assertTrue(DisplayName::isPlaceholder(null));
    }

    public function testRejectionCarries422(): void
    {
        try {
            DisplayName::assertReal('09390039833');
            $this->fail('expected AppException');
        } catch (AppException $e) {
            $this->assertSame(422, $e->getHttpStatus());
            $this->assertStringContainsString('نام معتبر نیست', $e->getMessage());
        }
    }
}
