<?php

namespace App\Models\SelfPaced;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * LearningProgress Model
 *
 * Records which CourseSubTopics a Trainee has marked as read for a given Enrollment.
 * The unique constraint on (enrollment_id, subtopic_id) enforces monotonicity —
 * once marked read, a subtopic stays read (Property 5).
 *
 * @property int $id
 * @property int $enrollment_id
 * @property int $user_id
 * @property int $subtopic_id
 * @property int $topic_id
 * @property int $course_id
 * @property \Illuminate\Support\Carbon|null $marked_read_at
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 */
class LearningProgress extends Model
{
    protected $table = 'self_paced_learning_progress';

    protected $fillable = [
        'enrollment_id',
        'user_id',
        'subtopic_id',
        'topic_id',
        'course_id',
        'marked_read_at',
    ];

    protected $casts = [
        'marked_read_at' => 'datetime',
        'created_at'     => 'datetime',
        'updated_at'     => 'datetime',
    ];

    // =========================================================================
    // RELATIONSHIPS
    // =========================================================================

    public function enrollment(): BelongsTo
    {
        return $this->belongsTo(Enrollment::class, 'enrollment_id');
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function subtopic(): BelongsTo
    {
        return $this->belongsTo(CourseSubTopic::class, 'subtopic_id');
    }

    public function topic(): BelongsTo
    {
        return $this->belongsTo(CourseTopic::class, 'topic_id');
    }

    public function course(): BelongsTo
    {
        return $this->belongsTo(Course::class, 'course_id');
    }

    // =========================================================================
    // QUERY SCOPES
    // =========================================================================

    public function scopeForEnrollment($query, int $enrollmentId)
    {
        return $query->where('enrollment_id', $enrollmentId);
    }

    public function scopeForTopic($query, int $topicId)
    {
        return $query->where('topic_id', $topicId);
    }

    public function scopeForCourse($query, int $courseId)
    {
        return $query->where('course_id', $courseId);
    }

    // =========================================================================
    // HELPER METHODS
    // =========================================================================

    /**
     * Mark a subtopic as read for an enrollment (idempotent — uses firstOrCreate).
     */
    public static function markRead(int $enrollmentId, int $userId, int $subtopicId, int $topicId, int $courseId): self
    {
        return static::firstOrCreate(
            ['enrollment_id' => $enrollmentId, 'subtopic_id' => $subtopicId],
            [
                'user_id'        => $userId,
                'topic_id'       => $topicId,
                'course_id'      => $courseId,
                'marked_read_at' => now(),
            ]
        );
    }
}
