<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Modules\Results\Models\Result;
use Modules\Students\Models\Student;
use Modules\Academic\Models\ExamType;
use Modules\Academic\Models\Subject;
use Modules\Academic\Models\Classroom;
use Modules\Academic\Models\AcademicYear;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\Modules\Results\app\Models\Result>
 */
class ResultFactory extends Factory
{
    protected $model = Result::class;

    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'student_id' => Student::factory(),
            'subject_id' => Subject::factory(),
            'classroom_id' => Classroom::factory(),
            'academic_year_id' => AcademicYear::factory(),
            'exam_type_id' => ExamType::factory(),
            'marks' => $this->faker->numberBetween(0, 100),
            'grade' => $this->faker->randomElement(['A+', 'A', 'B+', 'B', 'C+', 'C', 'D', 'F']),
            'points' => $this->faker->numberBetween(1, 10),
            'teacher_id' => \App\Models\User::factory()->teacher(),
            'entered_at' => $this->faker->dateTimeBetween('-1 month', 'now'),
        ];
    }

    /**
     * Indicate that the result is excellent.
     */
    public function excellent(): static
    {
        return $this->state(fn (array $attributes) => [
            'marks' => $this->faker->numberBetween(90, 100),
            'grade' => $this->faker->randomElement(['A+', 'A']),
            'points' => $this->faker->numberBetween(9, 10),
        ]);
    }

    /**
     * Indicate that the result is good.
     */
    public function good(): static
    {
        return $this->state(fn (array $attributes) => [
            'marks' => $this->faker->numberBetween(75, 89),
            'grade' => $this->faker->randomElement(['B+', 'B']),
            'points' => $this->faker->numberBetween(7, 8),
        ]);
    }

    /**
     * Indicate that the result is average.
     */
    public function average(): static
    {
        return $this->state(fn (array $attributes) => [
            'marks' => $this->faker->numberBetween(60, 74),
            'grade' => $this->faker->randomElement(['C+', 'C']),
            'points' => $this->faker->numberBetween(5, 6),
        ]);
    }

    /**
     * Indicate that the result is poor.
     */
    public function poor(): static
    {
        return $this->state(fn (array $attributes) => [
            'marks' => $this->faker->numberBetween(0, 59),
            'grade' => $this->faker->randomElement(['D', 'F']),
            'points' => $this->faker->numberBetween(1, 4),
        ]);
    }

    /**
     * Create result for a specific student.
     */
    public function forStudent($student): static
    {
        return $this->state(fn (array $attributes) => [
            'student_id' => $student instanceof Student ? $student->id : $student,
        ]);
    }

    /**
     * Create result for a specific exam type.
     */
    public function forExamType($examType): static
    {
        return $this->state(fn (array $attributes) => [
            'exam_type_id' => $examType instanceof ExamType ? $examType->id : $examType,
        ]);
    }

    /**
     * Create result for a specific subject.
     */
    public function forSubject($subject): static
    {
        return $this->state(fn (array $attributes) => [
            'subject_id' => $subject instanceof Subject ? $subject->id : $subject,
        ]);
    }
}
