<?php

namespace App\Tests\Insurance;

use App\Insurance\Enum\ServiceCategory;
use App\Insurance\Service\TenantServiceCategoryService;
use App\Shared\Exception\AppException;
use App\Tests\ApiTestCase;

/**
 * The tenant-wide switch for insurance service kinds. A tenant with no stored rows
 * keeps every kind enabled, and the last enabled kind can never be turned off.
 */
class TenantServiceCategoryServiceTest extends ApiTestCase
{
    private TenantServiceCategoryService $service;
    private int $entityId;

    protected function setUp(): void
    {
        parent::setUp();
        $this->service  = static::getContainer()->get(TenantServiceCategoryService::class);
        // db_test is never reset — a fresh id per test keeps rows from leaking across cases.
        $this->entityId = random_int(100_000, 999_999);
    }

    public function testEveryKindIsEnabledWithoutStoredRows(): void
    {
        $this->assertSame(ServiceCategory::values(), $this->service->enabledKeys('doctor', $this->entityId));
        $this->assertNull($this->service->defaultCategory('doctor', $this->entityId));
    }

    public function testSettingsRowsAlwaysCoverEveryKind(): void
    {
        $rows = $this->service->settingsRows('doctor', $this->entityId);

        $this->assertSame(ServiceCategory::values(), array_column($rows, 'key'));
        $this->assertSame([true, true], array_column($rows, 'enabled'));
    }

    public function testSingleEnabledKindBecomesTheDefault(): void
    {
        $this->service->save('doctor', $this->entityId, [
            ['key' => 'inpatient', 'enabled' => false],
        ]);

        $this->assertSame(['outpatient'], $this->service->enabledKeys('doctor', $this->entityId));
        $this->assertSame(ServiceCategory::Outpatient, $this->service->defaultCategory('doctor', $this->entityId));
        $this->assertFalse($this->service->isEnabled('doctor', $this->entityId, ServiceCategory::Inpatient));
    }

    public function testBothEnabledLeavesTheChoiceToTheUser(): void
    {
        $this->service->save('doctor', $this->entityId, [
            ['key' => 'outpatient', 'enabled' => true],
            ['key' => 'inpatient',  'enabled' => true],
        ]);

        $this->assertNull($this->service->defaultCategory('doctor', $this->entityId));
    }

    public function testDisablingEveryKindIsRejected(): void
    {
        $this->expectException(AppException::class);

        $this->service->save('doctor', $this->entityId, [
            ['key' => 'outpatient', 'enabled' => false],
            ['key' => 'inpatient',  'enabled' => false],
        ]);
    }

    public function testDisablingTheLastRemainingKindIsRejected(): void
    {
        $this->service->save('doctor', $this->entityId, [['key' => 'inpatient', 'enabled' => false]]);

        $this->expectException(AppException::class);
        $this->service->save('doctor', $this->entityId, [['key' => 'outpatient', 'enabled' => false]]);
    }

    public function testUnknownKindIsRejected(): void
    {
        $this->expectException(AppException::class);

        $this->service->save('doctor', $this->entityId, [['key' => 'dental', 'enabled' => true]]);
    }

    public function testSettingsAreIsolatedPerTenant(): void
    {
        $this->service->save('doctor', $this->entityId, [['key' => 'inpatient', 'enabled' => false]]);

        $this->assertSame(['outpatient'], $this->service->enabledKeys('doctor', $this->entityId));
        $this->assertSame(ServiceCategory::values(), $this->service->enabledKeys('clinic', $this->entityId));
    }
}
