<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Project extends BaseModel
{
    /**
     * Table name (your CI table is singular "project").
     */
    protected $table = 'project';

    /**
     * Mass assignment.
     */
    protected $fillable = [
        'student_id',
        'school_id',
        'class_section_id',
        'updated_by',
        'project_index',
        'score',
        'comment',
        'semester',
        'school_year',
        'created_at',
        'updated_at',
    ];

    /**
     * If your table has created_at/updated_at columns (it does),
     * keep timestamps enabled (default = true).
     */
    public $timestamps = true;

    /**
     * Helpful casts (adjust types if your DB columns differ).
     */
    protected $casts = [
        'student_id'        => 'integer',
        'school_id'         => 'integer',
        'class_section_id'  => 'integer',
        'updated_by'        => 'integer',
        'project_index'     => 'integer',
        'score'             => 'decimal:2', // or 'float' if you prefer
        'created_at'        => 'datetime',
        'updated_at'        => 'datetime',
    ];

    /* ============================================================
     * Relationships (optional but useful)
     * ============================================================
     */

    public function student(): BelongsTo
    {
        return $this->belongsTo(Student::class, 'student_id');
    }

    public function classSection(): BelongsTo
    {
        return $this->belongsTo(ClassSection::class, 'class_section_id');
    }

    public function school(): BelongsTo
    {
        return $this->belongsTo(School::class, 'school_id');
    }

    /* ============================================================
     * Query Scopes (reusable filters)
     * ============================================================
     */

    public function scopeForStudent(Builder $q, int $studentId): Builder
    {
        return $q->where('student_id', $studentId);
    }

    public function scopeForTerm(Builder $q, string $semester, string $schoolYear): Builder
    {
        return $q->where('semester', $semester)
                 ->where('school_year', $schoolYear);
    }

    public function scopeForClassSection(Builder $q, ?int $classSectionId): Builder
    {
        return $classSectionId !== null
            ? $q->where('class_section_id', $classSectionId)
            : $q;
    }

    /* ============================================================
     * Business: Average score
     * ============================================================
     */

    /**
     * Calculate average project score for a student + term (+ optional class section).
     *
     * Enhancements vs CI version:
     * - Uses SQL AVG for performance
     * - Ignores NULL, empty string, and non-numeric (best-effort) values
     * - Returns float|null
     */
    public static function averageScore(
        int $studentId,
        string $semester,
        string $schoolYear,
        ?int $classSectionId = null
    ): ?float {
        $avg = static::query()
            ->forStudent($studentId)
            ->forTerm($semester, $schoolYear)
            ->forClassSection($classSectionId)
            // ignore NULL and blank
            ->whereNotNull('score')
            ->whereRaw("TRIM(COALESCE(score, '')) <> ''")
            /**
             * If score is stored as VARCHAR and may contain junk,
             * this helps filter numeric-only values in MySQL.
             * If score is a numeric column, you can remove this line.
             */
            ->when(static::scoreMightBeString(), function (Builder $q) {
                $q->whereRaw("TRIM(score) REGEXP '^-?[0-9]+(\\.[0-9]+)?$'");
            })
            ->avg('score');

        return $avg === null ? null : (float) $avg;
    }

    /**
     * Instance method (so you can keep a similar calling style to CI).
     */
    public function getAverageProjectScore(
        int $studentId,
        string $semester,
        string $schoolYear,
        ?int $classSectionId = null
    ): ?float {
        return static::averageScore($studentId, $semester, $schoolYear, $classSectionId);
    }

    /**
     * Toggle the REGEXP filter depending on your schema.
     * If your `score` column is DECIMAL/INT/FLOAT, return false.
     */
    protected static function scoreMightBeString(): bool
    {
        // Safe default if you're unsure. Set to false if score is numeric.
        return true;
    }
}