<?php

declare(strict_types=1);

namespace Tests\Integration;

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

final class QuestionnaireEditingTest extends QdbTestCase
{
    public function testAdminCreatesQuestion(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $f = $this->fixture();
        $res = $this->api()->withToken($token, 'POST', 'questions', [
            'questionnaireID' => $f->questionnaireId,
            'questionKey'     => 'extra_q',
            'defaultText'     => 'Extra question text',
            'type'            => 'free_text',
            'isRequired'      => 0,
            'configJson'      => '{}',
        ]);
        $this->assertApiOk($res);
        $this->assertSame('extra_q', $res['data']['question']['questionKey'] ?? '');
    }

    public function testAdminCreatesAnswerOption(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $f = $this->fixture();
        $res = $this->api()->withToken($token, 'POST', 'answer_options', [
            'questionID'  => $f->questionId,
            'optionKey'   => 'no_option',
            'defaultText' => 'No',
            'points'      => 0,
        ]);
        $this->assertApiOk($res);
        $this->assertSame('no_option', $res['data']['answerOption']['optionKey'] ?? '');
    }

    public function testAnswerOptionsRequireQuestionId(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'answer_options');
        $this->assertApiError($res, 'MISSING_PARAM', 400);
    }

    public function testSavingNoteBeforeBumpsStructureRevisionAndExportsKey(): void
    {
        $adminToken = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $coachLogin = $this->api()->loginMobileAndGetToken(
            DatabaseSeeder::COACH_USERNAME,
            DatabaseSeeder::PASSWORD
        );
        $f = $this->fixture();

        $before = $this->api()->withMobileToken($coachLogin['token'], 'GET', 'app_questionnaires', null, [
            'id' => $f->questionnaireId,
        ]);
        $this->assertApiOk($before);
        $revBefore = (int)($before['data']['structureRevision'] ?? 1);

        $put = $this->api()->withToken($adminToken, 'PUT', 'questions', [
            'questionID'  => $f->questionId,
            'questionKey' => 'consent_q',
            'defaultText' => 'Consent?',
            'type'        => 'single_choice_question',
            'isRequired'  => 1,
            'configJson'  => json_encode(['questionKey' => 'consent_q'], JSON_UNESCAPED_UNICODE),
            'noteBefore'  => 'Bitte dem Klienten deutlich machen: Ohne Einwilligung keine Teilnahme.',
            'noteAfter'   => '',
        ]);
        $this->assertApiOk($put);
        $revAfter = (int)($put['data']['structureRevision'] ?? 0);
        $this->assertGreaterThan($revBefore, $revAfter, 'note-only edit must bump structureRevision for app sync');

        $detail = $this->api()->withMobileToken($coachLogin['token'], 'GET', 'app_questionnaires', null, [
            'id' => $f->questionnaireId,
        ]);
        $this->assertApiOk($detail);
        $questions = $detail['data']['questions'] ?? [];
        $this->assertIsArray($questions);
        $matched = null;
        foreach ($questions as $q) {
            if (($q['question'] ?? '') === 'consent_q' || ($q['id'] ?? '') === 'q1') {
                $matched = $q;
                break;
            }
        }
        $this->assertNotNull($matched, 'expected consent question in app export');
        $this->assertSame('consent_q_note_before', $matched['noteBeforeKey'] ?? null);
        $de = $detail['data']['translations']['de'] ?? [];
        $this->assertSame(
            'Bitte dem Klienten deutlich machen: Ohne Einwilligung keine Teilnahme.',
            $de['consent_q_note_before'] ?? null
        );
    }
}
