<?php

declare(strict_types=1);

namespace Tests\Integration;

use Tests\Support\DatabaseSeeder;
use Tests\Support\QdbTestCase;

final class CatalogApiTest extends QdbTestCase
{
    public function testListLanguages(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'translations', null, ['languages' => '1']);
        $this->assertApiOk($res);
        $this->assertIsArray($res['data']['languages']);
    }

    public function testListQuestionsForQuestionnaire(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $f = $this->fixture();
        $res = $this->api()->withToken($token, 'GET', 'questions', null, [
            'questionnaireID' => $f->questionnaireId,
        ]);
        $this->assertApiOk($res);
        $ids = array_column($res['data']['questions'], 'questionID');
        $this->assertContains($f->questionId, $ids);
    }

    public function testListAnswerOptions(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'answer_options', null, [
            'questionID' => $this->fixture()->questionId,
        ]);
        $this->assertApiOk($res);
        $this->assertNotEmpty($res['data']['answerOptions']);
    }

    public function testListCoachesForSupervisor(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::SUPERVISOR_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'coaches');
        $this->assertApiOk($res);
        $coachIds = array_column($res['data']['coaches'], 'coachID');
        $this->assertContains($this->fixture()->coachId, $coachIds);
    }

    public function testTranslationsAllDashboard(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'translations', null, ['all' => '1']);
        $this->assertApiOk($res);
        $this->assertArrayHasKey('questionnaires', $res['data']);
        $this->assertArrayHasKey('entries', $res['data']);
    }

    public function testTranslationsForQuestionnaire(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'translations', null, [
            'questionnaireID' => $this->fixture()->questionnaireId,
        ]);
        $this->assertApiOk($res);
        $this->assertArrayHasKey('entries', $res['data']);
    }

    public function testAppTranslationsRequiresAuth(): void
    {
        $res = $this->api()->request('GET', 'app_questionnaires', null, [], ['translations' => '1']);
        $this->assertApiError($res, 'UNAUTHORIZED', 401);
    }

    public function testAppLoginTranslationsPublicNoAuth(): void
    {
        $res = $this->api()->request('GET', 'app_questionnaires', null, [], ['loginTranslations' => '1']);
        $this->assertApiOk($res);
        $this->assertArrayHasKey('translations', $res['data']);
        $map = $res['data']['translations'];
        $this->assertIsArray($map);
        // Must include auth / help_auth keys and must not dump unrelated catalog keys.
        $foundAuth = false;
        $foundHelp = false;
        $forbidden = false;
        foreach ($map as $lang => $strings) {
            $this->assertIsArray($strings);
            foreach ($strings as $key => $text) {
                $this->assertTrue(
                    qdb_is_public_login_translation_key((string)$key),
                    "Unexpected public key: {$key}"
                );
                if (str_starts_with((string)$key, 'auth_')) {
                    $foundAuth = true;
                }
                if (str_starts_with((string)$key, 'help_auth_')) {
                    $foundHelp = true;
                }
                if ((string)$key === 'client_code' || (string)$key === 'client_picker_title') {
                    $forbidden = true;
                }
            }
        }
        $this->assertTrue($foundAuth);
        $this->assertTrue($foundHelp);
        $this->assertFalse($forbidden);
    }

    public function testAppTranslationsWithToken(): void
    {
        $login = $this->api()->loginMobileAndGetToken(
            DatabaseSeeder::COACH_USERNAME,
            DatabaseSeeder::PASSWORD
        );
        $res = $this->api()->withMobileToken($login['token'], 'GET', 'app_questionnaires', null, [
            'translations' => '1',
        ]);
        $this->assertApiOk($res);
        $this->assertArrayHasKey('translations', $res['data']);
    }
}
