<?php

namespace App\Models\SelfPaced;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * ExamQuestion Model
 *
 * A single multiple-choice question in the question bank for a Course.
 * Each question has four options (A-D) and a designated correct answer.
 *
 * @property int $id
 * @property int $course_id
 * @property string $question_text
 * @property string $option_a
 * @property string $option_b
 * @property string $option_c
 * @property string $option_d
 * @property string $correct_answer
 * @property string|null $explanation
 * @property int $sort_order
 * @property bool $is_active
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 */
class ExamQuestion extends Model
{
    protected $table = 'self_paced_exam_questions';

    protected $fillable = [
        'course_id',
        'topic_id',
        'question_text',
        'question_text_html',
        'option_a',
        'option_b',
        'option_c',
        'option_d',
        'correct_answer',
        'allow_multiple_answers',
        'correct_answers_json',
        'explanation',
        'question_media_path',
        'question_media_type',
        'question_media_name',
        'question_media_size',
        'upload_required',
        'upload_label',
        'sort_order',
        'is_active',
    ];

    protected $casts = [
        'sort_order'             => 'integer',
        'is_active'              => 'boolean',
        'upload_required'        => 'boolean',
        'allow_multiple_answers' => 'boolean',
        'correct_answers_json'   => 'array',
        'question_media_size'    => 'integer',
        'created_at'             => 'datetime',
        'updated_at'             => 'datetime',
    ];

    protected $attributes = [
        'sort_order' => 0,
        'is_active'  => true,
    ];

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

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

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

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

    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

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

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

    /**
     * Get the text of a given option letter (A, B, C, or D).
     */
    public function getOptionText(string $letter): string
    {
        return match (strtoupper($letter)) {
            'A' => $this->option_a,
            'B' => $this->option_b,
            'C' => $this->option_c,
            'D' => $this->option_d,
            default => '',
        };
    }

    /**
     * Check whether a given answer is correct.
     * For single-answer: $answer is a string like 'A'.
     * For multi-answer:  $answer is a sorted comma-separated string like 'A,C'
     *                    or an array ['A','C'].
     */
    public function isCorrect(string|array $answer): bool
    {
        if ($this->allow_multiple_answers) {
            $correct = $this->correct_answers_json ?? [];
            sort($correct);

            if (is_array($answer)) {
                $given = $answer;
            } else {
                // Stored as comma-separated: "A,C"
                $given = array_filter(array_map('trim', explode(',', strtoupper($answer))));
            }
            sort($given);

            return $given === $correct;
        }

        // Single answer
        $given = is_array($answer) ? implode(',', $answer) : $answer;
        return strtoupper(trim($given)) === strtoupper($this->correct_answer ?? '');
    }

    /**
     * Get the correct answer display string for results view.
     */
    public function getCorrectAnswerDisplay(): string
    {
        if ($this->allow_multiple_answers) {
            $answers = $this->correct_answers_json ?? [];
            sort($answers);
            return implode(' & ', $answers);
        }
        return $this->correct_answer ?? '';
    }

    /**
     * Whether this question has an attached media file.
     */
    public function hasMedia(): bool
    {
        return !empty($this->question_media_path);
    }

    /**
     * Get formatted file size for display.
     */
    public function getFormattedMediaSize(): string
    {
        if (!$this->question_media_size) return '';
        $kb = $this->question_media_size / 1024;
        if ($kb < 1024) return number_format($kb, 1) . ' KB';
        return number_format($kb / 1024, 2) . ' MB';
    }
}
