<?php

namespace App\Tests\Insurance;

use App\Insurance\Entity\Insurance;
use App\Insurance\Enum\InsuranceType;
use App\Tests\ApiTestCase;

/**
 * Admin-only endpoints managing the central coverage percentages of an insurance.
 */
class CoverageDefaultsApiTest extends ApiTestCase
{
    private function makeInsurance(): Insurance
    {
        $insurance = new Insurance('بیمه تست پوشش ' . random_int(1000, 9999), InsuranceType::Basic);
        $this->em->persist($insurance);
        $this->em->flush();

        return $insurance;
    }

    public function testAdminGetsEveryServiceCategory(): void
    {
        $admin     = $this->createUser(['ROLE_ADMIN']);
        $insurance = $this->makeInsurance();

        $body = $this->authJson('GET', '/api/v1/admin/insurance/' . $insurance->getId() . '/coverage-defaults', $admin);

        $this->assertSame(200, $this->responseCode());
        $keys = array_column($body['data']['categories'], 'key');
        $this->assertContains('outpatient', $keys);
        $this->assertContains('inpatient', $keys);
    }

    public function testAdminSavesPercentages(): void
    {
        $admin     = $this->createUser(['ROLE_ADMIN']);
        $insurance = $this->makeInsurance();

        $body = $this->authJson('PUT', '/api/v1/admin/insurance/' . $insurance->getId() . '/coverage-defaults', $admin, [
            'categories' => [
                ['key' => 'outpatient', 'coverage_percent' => 70],
                ['key' => 'inpatient',  'coverage_percent' => 30],
            ],
        ]);

        $this->assertSame(200, $this->responseCode());
        $percents = array_column($body['data']['categories'], 'coverage_percent', 'key');
        $this->assertEquals(70.0, $percents['outpatient']);
        $this->assertEquals(30.0, $percents['inpatient']);
    }

    public function testPercentAbove100IsRejected(): void
    {
        $admin     = $this->createUser(['ROLE_ADMIN']);
        $insurance = $this->makeInsurance();

        $this->authJson('PUT', '/api/v1/admin/insurance/' . $insurance->getId() . '/coverage-defaults', $admin, [
            'categories' => [['key' => 'outpatient', 'coverage_percent' => 101]],
        ]);

        $this->assertSame(422, $this->responseCode());
    }

    public function testUnknownCategoryIsRejected(): void
    {
        $admin     = $this->createUser(['ROLE_ADMIN']);
        $insurance = $this->makeInsurance();

        $this->authJson('PUT', '/api/v1/admin/insurance/' . $insurance->getId() . '/coverage-defaults', $admin, [
            'categories' => [['key' => 'dental', 'coverage_percent' => 50]],
        ]);

        $this->assertSame(422, $this->responseCode());
    }

    public function testNonAdminIsForbidden(): void
    {
        $doctor    = $this->createUser(['ROLE_DOCTOR']);
        $insurance = $this->makeInsurance();

        $this->authJson('GET', '/api/v1/admin/insurance/' . $insurance->getId() . '/coverage-defaults', $doctor);
        $this->assertSame(403, $this->responseCode());

        $this->authJson('PUT', '/api/v1/admin/insurance/' . $insurance->getId() . '/coverage-defaults', $doctor, [
            'categories' => [['key' => 'outpatient', 'coverage_percent' => 50]],
        ]);
        $this->assertSame(403, $this->responseCode());
    }

    public function testMissingInsuranceIsNotFound(): void
    {
        $admin = $this->createUser(['ROLE_ADMIN']);

        $this->authJson('GET', '/api/v1/admin/insurance/99999999/coverage-defaults', $admin);

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