<?php

namespace App\Models;

use App\Models\Scopes\ScoalaThroughClasaScope;
use App\Models\Traits\LogsActivity;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;

class Elev extends Model
{
    use Notifiable, LogsActivity;
    protected $table = 'elevi';

    protected static function booted(): void
    {
        static::addGlobalScope(new ScoalaThroughClasaScope());
    }

    protected $fillable = [
        'clasa_id',
        'user_id',
        'parinte_user_id',
        'nume',
        'prenume',
        'data_nasterii',
        'cnp',
        'email_parinte',
        'telefon_parinte',
    ];

    public function routeNotificationForMail(): ?string
    {
        return $this->email_parinte;
    }

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

    public function parinte()
    {
        return $this->belongsTo(User::class, 'parinte_user_id');
    }

    public function clasa()
    {
        return $this->belongsTo(Clasa::class);
    }

    public function note()
    {
        return $this->hasMany(Nota::class);
    }

    public function absente()
    {
        return $this->hasMany(Absenta::class);
    }

    public function notePurtare()
    {
        return $this->hasMany(NotaPurtare::class);
    }

    public function medii()
    {
        return $this->hasMany(Medie::class);
    }

    public function situatiiScolare()
    {
        return $this->hasMany(SituatieScolara::class);
    }

    public function corigente()
    {
        return $this->hasMany(Corigenta::class);
    }

    public function transferuri()
    {
        return $this->hasMany(Transfer::class);
    }

    public function observatii()
    {
        return $this->hasMany(ObservatieElev::class);
    }

    public function mediePeMaterie(int $materieId, int $semestru): ?float
    {
        $noteCurente = $this->note()
            ->where('materie_id', $materieId)
            ->where('semestru', $semestru)
            ->whereNotIn('tip', ['final', 'teza'])
            ->pluck('valoare');

        if ($noteCurente->isEmpty()) {
            return null;
        }

        $mediaAritmetica = $noteCurente->avg();

        if ($this->clasa?->cu_teze) {
            $teza = $this->note()
                ->where('materie_id', $materieId)
                ->where('semestru', $semestru)
                ->where('tip', 'teza')
                ->value('valoare');

            if ($teza !== null) {
                return round((3 * $mediaAritmetica + $teza) / 4, 2);
            }
        }

        return round($mediaAritmetica, 2);
    }

    // Media generală pe semestru
    public function medieGenerala(int $semestru): ?float
    {
        $materii = $this->clasa->materii;

        $medii = $materii->map(fn($m) => $this->mediePeMaterie($m->id, $semestru))
            ->filter(fn($m) => $m !== null);

        if ($medii->isEmpty()) {
            return null;
        }

        return round($medii->avg(), 2);
    }

    // Total absențe pe semestru
    public function totalAbsente(int $semestru): int
    {
        return $this->absente()
            ->where('semestru', $semestru)
            ->count();
    }

    // Absențe nemotivate pe semestru
    public function absenteNemotivate(int $semestru): int
    {
        return $this->absente()
            ->where('semestru', $semestru)
            ->where('motivata', false)
            ->count();
    }
}