<?php

namespace App\Jobs;

use App\Models\Classe;
use App\Models\Coefficient;
use App\Models\MoyenneBilan;
use App\Models\CuttingSchoolYear;
use App\Models\MoyenneDecoupageMatiere;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Events\BilanMatiereEvent;
use App\Jobs\BilanAnnuelJob;
use Illuminate\Support\Facades\DB;

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

    protected $student;
    protected $class; 
    protected $decoup;
    protected $bilan;
    protected $school;

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

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $dts = getClassement($this->getMoyenne());
        $cutting = CuttingSchoolYear::find($this->decoup);
        foreach($dts as $item){
            $exist = MoyenneBilan::where('inscription_id', $item['id'])->where('cutting_school_year_id', $this->decoup)->where('libelle_bilan_id', $this->bilan)->where('school_id', $this->school)->first();
            if($exist){
                $exist->update([
                    'rang' => $item['rang'],
                    'points' => $item['point'],
                    'coeffs' => $item['coeff'],
                    'moyenne' => $item['moyen'],
                ]);
            }
            else{
                $this->saveDataMoyenne($item['id'], $item['moyen'], $item['rang'], $item['point'], $item['coeff']);
            }

            // Déclenchement de l’événement
            event(new BilanMatiereEvent($item['id'], $item['moyen'], $item['rang'], $item['coeff'], $cutting->school_year_id, $cutting->cutting->libelle, $this->bilan, $this->school));
        }

        // Déclenchement de Job pour le calcul des moyennes Annuelles .................
        if($cutting->cutting->end == 'oui'){
            BilanAnnuelJob::dispatch($this->student, $this->bilan, $cutting->school_year_id)->delay(now()->addSeconds(1));
        }
    }


    protected function getMoyenne()
    {
        $tabeau = [];
        foreach ($this->student as $item) {
            $resut = $this->calculMoyenne($item->id);
            $tabeau[] = [
                'id' => $item->id,
                'sexe' => $item->sexe,
                'moyen' => $resut[0],
                'point' => $resut[1],
                'coeff' => $resut[2]
            ];
        }
        return $tabeau;
    }


    protected function calculMoyenne($item)
    {
        $point = 0; $coefs = 0; $exist = false;
        $matieres = $this->getMatterBilan();
        foreach($matieres as $matiere){
            $moyen = $this->moyenneFirst($item, $matiere['id']);
            if($moyen && $moyen != 'nc'){
                $coef = Coefficient::find($matiere['coefficient_id']);
                $point += ($moyen * $coef['valeur']);
                $coefs += $coef['valeur']; $exist = true;
            }
        }
        $moyen = $exist ? ($point ? number_format(($point / $coefs), 2, '.', ' '):'0'):'nc';
        return [($exist ? ($moyen < 10 ? '0'.$moyen:$moyen):$moyen), $point, $coefs];
    }


    protected function moyenneFirst($id1, $id2)
    {
        $moy = MoyenneDecoupageMatiere::where('inscription_id', $id1)->where('level_matter_id', $id2)->where('cutting_school_year_id', $this->decoup)->first();
        return $moy ? $moy->moyenne:null;
    }


    protected function getMatterBilan()
    {
        $class = Classe::find($this->class);
        $dts = DB::table('matters')
        ->join('level_matter', 'matters.id', '=', 'level_matter.matter_id')
        ->join('libelle_bilan_matter', 'matters.id', '=', 'libelle_bilan_matter.matter_id')
        ->select('level_matter.id', 'matters.abbreviated', 'level_matter.coefficient_id')
        ->where('libelle_bilan_matter.libelle_bilan_id', '=', $this->bilan)
        ->where('level_matter.level_id', '=', $class['level_id'])
        ->where('level_matter.serie_id', '=', $class['serie'])
        ->where('libelle_bilan_matter.type', '=', $class['type'])->get();

        return json_decode($dts, true);
    }


    protected function saveDataMoyenne($student, $moyen, $rang, $point, $coeffs)
    {
        MoyenneBilan::create([
            'rang' => $rang,
            'points' => $point,
            'moyenne' => $moyen,
            'coeffs' => $coeffs,
            'inscription_id' => $student,
            'school_id' => $this->school,
            'libelle_bilan_id' => $this->bilan,
            'cutting_school_year_id' => $this->decoup
        ]);
    }
}
