<?php

namespace App\Tests\Branch;

use App\Doctor\Entity\DoctorAddress;

/**
 * دو ویژگی تازهٔ شعبه (`active` / `timezone`) و فهرست شعبه‌های محیط جاری.
 */
class BranchFieldsTest extends BranchTestCase
{
    /** ردیف‌های موجود بدون backfill درست می‌شوند؛ هیچ رفتار فعلی عوض نمی‌شود. */
    public function testExistingBranchGetsSafeDefaults(): void
    {
        [$user, , $address] = $this->doctorWithAddress();

        self::assertTrue($address->isActive());
        self::assertSame(DoctorAddress::DEFAULT_TIMEZONE, $address->getTimezone());

        $body = $this->authJson('GET', '/api/v1/branches', $user);

        self::assertSame(200, $this->responseCode());
        self::assertTrue($body['data'][0]['active']);
        self::assertSame('Asia/Tehran', $body['data'][0]['timezone']);
    }

    public function testListReportsWorkingHoursAndRoomCounts(): void
    {
        [$user, , $address] = $this->doctorWithAddress();

        $before = $this->authJson('GET', '/api/v1/branches', $user);
        self::assertFalse($before['data'][0]['working_hours_defined']);
        self::assertSame(0, $before['data'][0]['rooms_count']);

        $this->authJson('PUT', "/api/v1/branch/{$address->getUuid()}/working-hours", $user, [
            'days' => [1 => [['start_minute' => 540, 'end_minute' => 780]]],
        ]);
        $this->authJson('POST', '/api/v1/room', $user, [
            'address_uuid' => $address->getUuid(),
            'name'         => 'اتاق ۱',
        ]);

        $after = $this->authJson('GET', '/api/v1/branches', $user);

        self::assertTrue($after['data'][0]['working_hours_defined']);
        self::assertSame(1, $after['data'][0]['rooms_count']);
    }

    /** فقط اتاق فعال شمرده می‌شود — اتاق غیرفعال ظرفیت واقعی شعبه نیست. */
    public function testInactiveRoomIsNotCounted(): void
    {
        [$user, , $address] = $this->doctorWithAddress();
        $room = $this->authJson('POST', '/api/v1/room', $user, [
            'address_uuid' => $address->getUuid(),
            'name'         => 'اتاق بسته',
        ]);
        $this->authJson('PATCH', "/api/v1/room/{$room['data']['uuid']}", $user, ['active' => false]);

        $body = $this->authJson('GET', '/api/v1/branches', $user);

        self::assertSame(0, $body['data'][0]['rooms_count']);
    }

    public function testListShowsOnlyTheCurrentContextBranches(): void
    {
        [$doctorUser, , $doctorAddress] = $this->doctorWithAddress('مطب شخصی');
        $this->clinicWithAddress('شعبهٔ کلینیک بیگانه');

        $body = $this->authJson('GET', '/api/v1/branches', $doctorUser);

        self::assertCount(1, $body['data']);
        self::assertSame($doctorAddress->getUuid(), $body['data'][0]['uuid']);
    }

    public function testBranchIsDeactivated(): void
    {
        [$user, , $address] = $this->doctorWithAddress();

        $body = $this->authJson('PATCH', "/api/v1/branch/{$address->getUuid()}", $user, ['active' => false]);

        self::assertSame(200, $this->responseCode());
        self::assertFalse($body['data']['active']);
    }

    public function testTimezoneIsUpdated(): void
    {
        [$user, , $address] = $this->doctorWithAddress();

        $body = $this->authJson('PATCH', "/api/v1/branch/{$address->getUuid()}", $user, [
            'timezone' => 'Asia/Dubai',
        ]);

        self::assertSame(200, $this->responseCode());
        self::assertSame('Asia/Dubai', $body['data']['timezone']);
    }

    /** با DateTimeZone::listIdentifiers سنجیده می‌شود، نه با regex. */
    public function testUnknownTimezoneIsRejected(): void
    {
        [$user, , $address] = $this->doctorWithAddress();

        $body = $this->authJson('PATCH', "/api/v1/branch/{$address->getUuid()}", $user, ['timezone' => 'Tehran']);

        self::assertSame(422, $this->responseCode());
        self::assertSame('timezone', $body['errors'][0]['field']);
    }

    public function testForeignBranchCannotBePatched(): void
    {
        [$doctorUser] = $this->doctorWithAddress();
        [, , $foreignAddress] = $this->clinicWithAddress();

        $this->authJson('PATCH', "/api/v1/branch/{$foreignAddress->getUuid()}", $doctorUser, ['active' => false]);

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

    /** شمارش‌ها گروهی‌اند: تعداد کوئری‌ها با تعداد شعبه‌ها رشد نمی‌کند. */
    public function testListQueryCountDoesNotGrowWithBranches(): void
    {
        // یک کرنل برای هر دو اندازه‌گیری، وگرنه reboot دادهٔ کوئری‌ها را می‌ریزد.
        $this->client->disableReboot();

        [$user, $doctor] = $this->doctorWithAddress();

        $queriesForOne = $this->countQueries(
            fn () => $this->authJson('GET', '/api/v1/branches', $user)
        );

        for ($i = 0; $i < 4; $i++) {
            $extra = DoctorAddress::forDoctor($doctor);
            $extra->setName("شعبهٔ $i");
            $this->em->persist($extra);
        }
        $this->em->flush();

        $queriesForFive = $this->countQueries(
            fn () => $this->authJson('GET', '/api/v1/branches', $user)
        );

        self::assertCount(5, json_decode($this->client->getResponse()->getContent(), true)['data']);
        self::assertSame($queriesForOne, $queriesForFive);
    }
}
