<?php

namespace App\Tests\Doctor;

use App\Doctor\Entity\Doctor;
use App\Doctor\Service\IrimcDegreeMapper;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

/**
 * تا ۱۴۰۵/۰۴/۲۸ خزندهٔ irimc دو کد را جابه‌جا می‌فرستاد: «فوق تخصص» را specialist
 * (برچسب: متخصص) و «تخصص» را expert (برچسب: فوق تخصص). نتیجه‌اش ۱۸۸۵ پزشک با درجهٔ
 * غلط بود — مثلاً «تخصص جراحی استخوان و مفاصل (ارتوپدی)» که «فوق تخصص» نمایش می‌داد.
 *
 * این تست قرارداد نگاشت را قفل می‌کند تا جابه‌جایی دوباره اتفاق نیفتد.
 */
class IrimcDegreeMappingTest extends TestCase
{
    #[DataProvider('titles')]
    public function testDegreeFromIrimcTitle(?string $title, ?string $expected): void
    {
        $this->assertSame($expected, IrimcDegreeMapper::fromTitle($title));
    }

    public static function titles(): array
    {
        return [
            // همان رکوردی که باگ را لو داد (پزشک #2269)
            'takhasos with general doctorate' => [
                'تخصص جراحی استخوان و مفاصل (ارتوپدی) دکترای حرفه‌ای پزشکی',
                'specialist',
            ],
            'plain takhasos'      => ['تخصص بیماری‌های داخلی', 'specialist'],
            'motakhases'          => ['متخصص زنان و زایمان', 'specialist'],

            // «فوق تخصص» شامل «تخصص» است — ترتیب شرط‌ها باید این را درست بگیرد
            'fogh takhasos'       => ['فوق تخصص جراحی قلب و عروق', 'expert'],
            'fogh takhasos zwnj'  => ['فوق‌تخصص گوارش و کبد بالغین', 'expert'],

            // فلوشیپ بر همه مقدم است، حتی وقتی کنارش «تخصص» آمده
            'fellowship'          => ['فلوشیپ اکوکاردیوگرافی', 'subspecialistplus'],
            'fellowship w/ takh'  => ['فلوشیپ جراحی، تخصص چشم‌پزشکی', 'subspecialistplus'],

            // عمومی فقط وقتی هیچ تخصصی در عنوان نیست
            'general doctorate'   => ['دکترای حرفه‌ای پزشکی', 'general'],
            'general physician'   => ['پزشک عمومی', 'general'],

            // ناشناخته/خالی → null؛ درجهٔ غلط از نبودِ درجه بدتر است
            'unknown'             => ['کارشناس تغذیه', null],
            'empty'               => ['', null],
            'whitespace'          => ['   ', null],
            'null'                => [null, null],
        ];
    }

    #[DataProvider('titles')]
    public function testMappedDegreeIsAlwaysAValidEntityDegree(?string $title, ?string $expected): void
    {
        $degree = IrimcDegreeMapper::fromTitle($title);

        if ($degree !== null) {
            $this->assertContains($degree, Doctor::DEGREES);
        }
        $this->assertSame($expected, $degree);
    }

    public function testLabelsMatchTheAdminPanelWording(): void
    {
        // اگر این‌ها با DoctorDetailPage.tsx (DEGREE_LABELS) فرق کنند، دوباره
        // همان باگ «تخصص ↔ فوق تخصص» برمی‌گردد، این‌بار در لایهٔ نمایش.
        $this->assertSame('متخصص',      IrimcDegreeMapper::label('specialist'));
        $this->assertSame('فوق تخصص',   IrimcDegreeMapper::label('expert'));
        $this->assertSame('عمومی',      IrimcDegreeMapper::label('general'));
        $this->assertSame('فلوشیپ',     IrimcDegreeMapper::label('subspecialistplus'));
    }

    public function testEveryLabelKeyIsAKnownEntityDegree(): void
    {
        foreach (array_keys(IrimcDegreeMapper::LABELS) as $degree) {
            $this->assertTrue(IrimcDegreeMapper::isValid($degree), "«$degree» در Doctor::DEGREES نیست");
        }
        $this->assertFalse(IrimcDegreeMapper::isValid('nonsense'));
        $this->assertFalse(IrimcDegreeMapper::isValid(null));
    }
}
