<?php

namespace App\Jobs;

use App\Models\Classe;
use App\Models\PrimaryNote;
use App\Models\ResultatPrimaire;
use App\Models\LevelPrimaryMatters;
use App\Jobs\CalculResultatClassePrimaire;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;

class CalulMoyennePrimaireJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $class;
    protected $school;
    protected $yearActif;
    protected $evaluated;
    /**
     * Create a new job instance.
     */
    public function __construct($class, $school, $yearActif, $evaluated)
    {
        $this->class = $class;
        $this->school = $school;
        $this->yearActif = $yearActif;
        $this->evaluated = $evaluated;
    }

    /**
    * Get notes student the specified resource from storage.
    */
    protected function getStudentMoyen($class, $level_id)
    {
        $tabs = [];
        $students = $this->getNoteEvaluated($class, $level_id);
        foreach($students as $item){
            $tabs[] = [
                'moyen' => calculMoyennePrimary($item['notes'])['moyen'],
                'id' => $item['id'],
                'sexe' => $item['sexe'],
                'point' => calculMoyennePrimary($item['notes'])['point'],
            ];
        }
        return $tabs;
    }


    protected function getNoteEvaluated($class, $level_id)
    {
        $student = $this->getStudentClasse($class);
        $matters = LevelPrimaryMatters::where('level_id', $level_id)->get();
        $tabs = [];
        foreach($student as $item){
            $tabs[] = [
                'id' => $item->id,
                'sexe' => $item->sexe,
                'notes' => $this->noteStudent($item->id, $matters)
            ];
        }
        return $tabs;
    }

    protected function getStudentClasse($id)
    {
        $data = DB::table('students')
            ->join('inscriptions', 'students.id', '=', 'inscriptions.student_id')
            ->select('inscriptions.id', 'students.sexe')
            ->where('inscriptions.classe_id', '=', $id)
            ->where('inscriptions.school_year_id', '=', $this->yearActif)
            ->orderBy('students.first_name')->orderBy('students.last_name')
            ->get();
        return $data;
    }

    protected function noteStudent($id, $matters)
    {
        $data = [];
        foreach($matters as $matter){
            $data[] = [
                'note' => PrimaryNote::where('inscription_id', $id)->where('evaluated_level_id', $this->evaluated)->where('level_primary_matter_id', $matter->id)->first(),
                'valeur' => $matter->points
            ];
        }
        return $data;
    }


    private function saveItem($student, $moyen, $point, $rang)
    {
        $exist = $this->verifyItem($student);
        if($exist){
            $exist->update([
                'moyenne'  => $moyen,
                'point'  => $point,
                'rang'  => $rang,
            ]);
        }
        else{
            ResultatPrimaire::create([
                'moyenne'  => $moyen,
                'point'  => $point,
                'rang'  => $rang,
                'inscription_id' => $student,
                'evaluated_level_id' => $this->evaluated,
                'school_year_id' => $this->yearActif,
                'school_id'  => $this->school
            ]);
        }
    }


    private function verifyItem($student)
    {
        $exist = ResultatPrimaire::where('inscription_id', $student)->where('evaluated_level_id', $this->evaluated)->where('school_id', $this->school)->first();
        return $exist ?? null;
    }


    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $classe = Classe::where('id', $this->class)->first();
        $datas = getClassement($this->getStudentMoyen($classe['id'], $classe['level_id']));
        foreach($datas as $item){
            if($item){
                $this->saveItem($item['id'], $item['moyen'], $item['point'], $item['rang']);
            }
        }

        // attendre 10 secondes
        CalculResultatClassePrimaire::dispatch($this->class, $this->school, $this->evaluated)->delay(now()->addSeconds(1));
    }
}
