<?php

namespace App\Tests\Auth;

use App\Auth\Entity\User;
use App\Clinic\Entity\Clinic;
use App\Tests\ApiTestCase;

/**
 * مالکِ چند کلینیک باید بتواند به **هر** کدامشان سوییچ کند.
 *
 * `buildAvailableContexts` قبلاً از `ClinicRepository::findByUser()` استفاده می‌کرد
 * که `findOneBy` است و فقط اولین کلینیک را می‌داد. `switchContext` هم ورودی را با
 * همان فهرست می‌سنجد، پس کلینیک دوم اصلاً قابل انتخاب نبود.
 *
 * پیش از جداسازی محیط این فقط آزاردهنده بود؛ با فاز ۴ به بعد تبدیل به مسدودکننده
 * شد: محیطی که انتخاب نشود، `TenantFilter` دادهٔ آن را از خودِ مالکش هم پنهان
 * می‌کند. روی دادهٔ واقعی production دیده شد، نه در تست‌های ساختگی.
 */
class MultiClinicOwnerContextTest extends ApiTestCase
{
    /** @return array{0: User, 1: Clinic, 2: Clinic} */
    private function ownerOfTwoClinics(): array
    {
        $owner = $this->createUser(['ROLE_CLINIC']);

        $first = new Clinic($owner);
        $first->setName('کلینیک اول');
        $this->em->persist($first);

        $second = new Clinic($owner);
        $second->setName('کلینیک دوم');
        $this->em->persist($second);
        $this->em->flush();

        return [$owner, $first, $second];
    }

    private function switchTo(User $owner, Clinic $clinic): array
    {
        return $this->authJson('POST', '/api/v1/auth/switch-context', $owner, [
            'db_uuid' => $clinic->getUuid(),
            'type'    => 'clinic',
        ]);
    }

    /**
     * ✅ هر دو کلینیک قابل انتخاب‌اند.
     *
     * از راه خودِ switch سنجیده می‌شود، نه از فهرست: `switchContext` ورودی را با
     * همان `buildAvailableContexts` می‌سنجد، پس سوییچِ موفق یعنی محیط در فهرست بوده.
     */
    public function testBothOwnedClinicsCanBeSelected(): void
    {
        [$owner, $first, $second] = $this->ownerOfTwoClinics();

        $this->switchTo($owner, $first);
        self::assertSame(200, $this->responseCode(), 'کلینیک اول باید قابل انتخاب باشد');

        $this->switchTo($owner, $second);
        self::assertSame(200, $this->responseCode(), 'کلینیک دوم هم باید قابل انتخاب باشد');
    }

    /** ✅ سوییچ به کلینیک دوم واقعاً انجام می‌شود. */
    public function testTheOwnerCanSwitchToTheSecondClinic(): void
    {
        [$owner, , $second] = $this->ownerOfTwoClinics();

        $res = $this->authJson('POST', '/api/v1/auth/switch-context', $owner, [
            'db_uuid' => $second->getUuid(),
            'type'    => 'clinic',
        ]);

        self::assertSame(200, $this->responseCode());
        self::assertSame($second->getUuid(), $res['data']['context']['db_uuid']);
        self::assertSame('clinic', $res['data']['context']['role']);
    }

    /** ❌ کلینیکِ شخص دیگر همچنان قابل انتخاب نیست. */
    public function testAnotherOwnersClinicIsStillRefused(): void
    {
        [$owner] = $this->ownerOfTwoClinics();
        [, $strangersClinic] = $this->ownerOfTwoClinics();

        $this->authJson('POST', '/api/v1/auth/switch-context', $owner, [
            'db_uuid' => $strangersClinic->getUuid(),
            'type'    => 'clinic',
        ]);

        self::assertSame(403, $this->responseCode());
    }

    /**
     * ⚠️ مرزی: پس از سوییچ، دادهٔ همان کلینیک دیده می‌شود — این همان چیزی است که
     * پیش از رفع باگ غیرممکن بود.
     */
    public function testDataOfTheSecondClinicBecomesReachableAfterSwitching(): void
    {
        [$owner, , $second] = $this->ownerOfTwoClinics();

        $this->authJson('POST', '/api/v1/auth/switch-context', $owner, [
            'db_uuid' => $second->getUuid(),
            'type'    => 'clinic',
        ]);
        self::assertSame(200, $this->responseCode());

        $created = $this->authJson('POST', '/api/v1/my/payment-methods/bank-accounts', $owner, [
            'bank_name'      => 'ملی',
            'account_number' => '0101234567890',
        ]);
        self::assertSame(201, $this->responseCode());
        self::assertSame('clinic', $created['data']['entity_type']);

        $list = $this->authJson('GET', '/api/v1/my/payment-methods/bank-accounts', $owner);
        self::assertSame(['ملی'], array_column($list['data'], 'bank_name'));
    }
}
