<?php

declare(strict_types=1);

namespace Tests\Integration;

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

final class EditorCrudTest extends QdbTestCase
{
    public function testAdminUpdatesAndDeletesAnswerOption(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::ADMIN_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $f = $this->fixture();

        $create = $this->api()->withToken($token, 'POST', 'answer_options', [
            'questionID'  => $f->questionId,
            'optionKey'   => 'temp_opt',
            'defaultText' => 'Temporary',
            'points'      => 1,
        ]);
        $this->assertApiOk($create);
        $optId = $create['data']['answerOption']['answerOptionID'] ?? '';
        $this->assertNotSame('', $optId);

        $update = $this->api()->withToken($token, 'PUT', 'answer_options', [
            'answerOptionID' => $optId,
            'optionKey'      => 'temp_opt',
            'defaultText'    => 'Temporary updated',
            'points'         => 5,
        ]);
        $this->assertApiOk($update);
        $this->assertSame(5, $update['data']['answerOption']['points'] ?? 0);

        $del = $this->api()->withToken($token, 'DELETE', 'answer_options', [
            'answerOptionID' => $optId,
        ]);
        $this->assertApiOk($del);

        $list = $this->api()->withToken($token, 'GET', 'answer_options', null, [
            'questionID' => $f->questionId,
        ]);
        $this->assertApiOk($list);
        $ids = array_column($list['data']['answerOptions'], 'answerOptionID');
        $this->assertNotContains($optId, $ids);
    }

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

        $create = $this->api()->withToken($token, 'POST', 'questions', [
            'questionnaireID' => $f->questionnaireId,
            'questionKey'     => 'disposable_q',
            'defaultText'     => 'Disposable',
            'type'            => 'free_text_question',
            'isRequired'      => 0,
            'configJson'      => '{}',
        ]);
        $this->assertApiOk($create);
        $qid = $create['data']['question']['questionID'] ?? '';
        $this->assertNotSame('', $qid);

        $update = $this->api()->withToken($token, 'PUT', 'questions', [
            'questionID'  => $qid,
            'defaultText' => 'Disposable updated',
            'questionKey' => 'disposable_q',
        ]);
        $this->assertApiOk($update);
        $this->assertSame('Disposable updated', $update['data']['question']['defaultText'] ?? '');

        $del = $this->api()->withToken($token, 'DELETE', 'questions', [
            'questionID' => $qid,
        ]);
        $this->assertApiOk($del);

        $list = $this->api()->withToken($token, 'GET', 'questions', null, [
            'questionnaireID' => $f->questionnaireId,
        ]);
        $ids = array_column($list['data']['questions'], 'questionID');
        $this->assertNotContains($qid, $ids);
    }

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

        $before = $this->api()->withToken($token, 'GET', 'questions', null, [
            'questionnaireID' => $f->questionnaireId,
        ]);
        $this->assertApiOk($before);
        $ids = array_column($before['data']['questions'], 'questionID');
        $reversed = array_reverse($ids);

        $patch = $this->api()->withToken($token, 'PATCH', 'questions', [
            'questionnaireID' => $f->questionnaireId,
            'order'           => $reversed,
        ]);
        $this->assertApiOk($patch);

        $after = $this->api()->withToken($token, 'GET', 'questions', null, [
            'questionnaireID' => $f->questionnaireId,
        ]);
        $afterIds = array_column($after['data']['questions'], 'questionID');
        $this->assertSame($reversed, $afterIds);
    }
}
