<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Models\Answer;
use App\Models\Category;
use App\Models\Question;
use App\Models\QuestionGroup;
use App\Models\Session;
use App\Services\ScoringService;
use Tests\TestCase;

class ScoringTest extends TestCase
{
    public function test_calculate_score_counts_only_scored_yes_answers(): void
    {
        $user = $this->createAuthenticatedUser();
        $category = Category::factory()->create();
        $group = QuestionGroup::factory()->create(['category_id' => $category->id]);

        $scoredQuestion = Question::factory()->create([
            'question_group_id' => $group->id,
            'is_scored' => true,
        ]);

        $nonScoredQuestion = Question::factory()->create([
            'question_group_id' => $group->id,
            'is_scored' => false,
        ]);

        $session = Session::factory()->create([
            'category_id' => $category->id,
            'user_id' => $user->id,
        ]);

        Answer::factory()->create([
            'session_id' => $session->id,
            'question_id' => $scoredQuestion->id,
            'value' => 'yes',
        ]);

        Answer::factory()->create([
            'session_id' => $session->id,
            'question_id' => $nonScoredQuestion->id,
            'value' => 'yes',
        ]);

        $service = new ScoringService;

        $this->assertEquals(1, $service->calculateScore($session));
    }

    public function test_determine_result_returns_go_for_score_ten(): void
    {
        $service = new ScoringService;

        $this->assertEquals('go', $service->determineResult(10));
    }

    public function test_determine_result_returns_consult_leadership_for_score_nine(): void
    {
        $service = new ScoringService;

        $this->assertEquals('consult_leadership', $service->determineResult(9));
    }

    public function test_determine_result_returns_consult_leadership_for_score_five(): void
    {
        $service = new ScoringService;

        $this->assertEquals('consult_leadership', $service->determineResult(5));
    }

    public function test_determine_result_returns_no_go_for_score_four(): void
    {
        $service = new ScoringService;

        $this->assertEquals('no_go', $service->determineResult(4));
    }

    public function test_determine_result_returns_no_go_for_score_zero(): void
    {
        $service = new ScoringService;

        $this->assertEquals('no_go', $service->determineResult(0));
    }

    public function test_session_completion_persists_score_and_result(): void
    {
        $user = $this->createAuthenticatedUser();
        $category = Category::factory()->create();
        $group = QuestionGroup::factory()->create(['category_id' => $category->id]);

        $scoredQuestions = Question::factory()->count(10)->create([
            'question_group_id' => $group->id,
            'is_scored' => true,
        ]);

        $session = Session::factory()->create([
            'category_id' => $category->id,
            'user_id' => $user->id,
        ]);

        foreach ($scoredQuestions as $question) {
            Answer::factory()->create([
                'session_id' => $session->id,
                'question_id' => $question->id,
                'value' => 'yes',
            ]);
        }

        $this->put("/sessions/{$session->id}", ['complete' => true])
            ->assertRedirect("/sessions/{$session->id}/result");

        $session->refresh();

        $this->assertEquals(10, $session->score);
        $this->assertEquals('go', $session->result);
        $this->assertEquals('completed', $session->status);
        $this->assertNotNull($session->completed_at);
    }
}
