<?php

namespace Tests\Unit\Services\Scores;

use App\Services\Scores\SemesterScoreService;
use App\Services\Scores\AttendanceCalculator;
use App\Services\Scores\HomeworkCalculator;
use App\Services\Scores\ProjectCalculator;
use App\Services\Scores\QuizCalculator;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;

class SemesterScoreServiceTest extends TestCase
{
    use RefreshDatabase;

    public function test_update_student_scores_upserts_semester_scores(): void
    {
        DB::table('midterm_exam')->insert([
            'student_id' => 1,
            'school_id' => 'SCH1',
            'class_section_id' => 4,
            'updated_by' => 99,
            'score' => 88,
            'semester' => 'Fall',
            'school_year' => '2025-2026',
        ]);

        $service = new SemesterScoreService(
            new FakeAttendanceCalculator(),
            new FakeHomeworkCalculator(),
            new FakeQuizCalculator(),
            new FakeProjectCalculator()
        );

        $service->updateStudentScores([
            'student_id' => 1,
            'school_id' => 'SCH1',
            'class_section_id' => 4,
            'updated_by' => 99,
        ], 'Fall', '2025-2026');

        $row = DB::table('semester_scores')->where([
            'student_id' => 1,
            'class_section_id' => 4,
            'semester' => 'Fall',
            'school_year' => '2025-2026',
        ])->first();

        $this->assertNotNull($row);
        $this->assertSame(95.0, (float) $row->attendance_score);
        $this->assertSame(80.0, (float) $row->homework_avg);
        $this->assertSame(90.0, (float) $row->quiz_avg);
        $this->assertSame(100.0, (float) $row->project_avg);
        $this->assertSame(84.0, (float) $row->ptap_score);
        $this->assertSame(88.0, (float) $row->midterm_exam_score);
        $this->assertSame(88.6, (float) $row->semester_score);
    }
}

class FakeAttendanceCalculator extends AttendanceCalculator
{
    public function __construct()
    {
    }

    public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
    {
        return ['attendance_score' => 95.0];
    }
}

class FakeHomeworkCalculator extends HomeworkCalculator
{
    public function __construct()
    {
    }

    public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
    {
        return ['homework_avg' => 80.0];
    }
}

class FakeQuizCalculator extends QuizCalculator
{
    public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
    {
        return ['quiz_avg' => 90.0];
    }
}

class FakeProjectCalculator extends ProjectCalculator
{
    public function __construct()
    {
    }

    public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
    {
        return [
            'project_avg' => 100.0,
            'participation_score' => 70.0,
        ];
    }
}
