<br />
<b>Warning</b>:  Undefined variable $auth in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<br />
<b>Warning</b>:  Trying to access array offset on value of type null in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<?php

use Carbon\Carbon;
use App\Models\Note;
use App\Models\User;
use App\Models\Year;
use App\Models\Admin;
use App\Models\Brand;
use App\Models\Pension;
use App\Models\CashDesk;
use App\Models\Customer;
use App\Models\CarFolder;
use App\Models\ClassSchool;
use App\Models\StudentRank;
use App\Models\Subscription;
use App\Models\CustomerAffair;
use Illuminate\Support\Facades\Auth;

if (! function_exists('convert_amount')) {
    function convert_amount($amount) {
        $currency = "F CFA";
        if (is_numeric($amount)) {
            return number_format($amount, 2);
        }
        return 0;
    }
}

if (! function_exists('convert_number')) {
    function convert_number($amount) {
        if (is_numeric($amount)) {
            //return number_format($amount, 2);
            return number_format($amount, 2, ',',' ');
        }
        return 0;
    }
}
if (!function_exists('convert_amount_v2')) {
    function convert_amount_v2($amount) {
        if (is_numeric($amount)) {
            return number_format($amount, 0, '.', ' ');
        }
        return '0.00';
    }
}

if (! function_exists('getLogo')) {
    function getLogo() {
        return asset('apex.png');
    }
}
if (! function_exists('getHeader')) {
    function getHeader() {
        return asset('header.jpg');
    }
}
if (! function_exists('getNameApp')) {
    function getNameApp() {
        return "APEX";
    }
}

if (! function_exists('isAdminPrincipal')) {
    function isAdminPrincipal() {
        if(Auth::check()){
            $city = Auth::user()->int_id;
            if($city === 0) return true;
            else return false;
        } 
    }
}

if (! function_exists('getCityByAdmin')) {
    function getCityByAdmin($admin_id) {
        $admin = Admin::where('ad_id', '=', $admin_id)->first();
        if($admin) return $admin->int_id;
        else return 0;
    }
}
if (! function_exists('getNoteByStudentByClass')) {
    function getNoteByStudentByClass($student,$sous_mat,$sequence,$session,$class_id) {
        $note = Note::where('usr_id', $student)
        ->where('s_mat_id', $sous_mat)
        ->where('trim_id', $sequence)
        ->where('note_annee', $session)
        ->where('class_id', $class_id)
        ->first();
        return $note;
    }
}
if (! function_exists('getAdminByName')) {
    function getAdminByName($id) {
        $admin = Admin::where('ad_id', $id)->firstOrFail();
        return $admin->ad_name;
    }
}
if (! function_exists('getClassNameSchool')) {
    function getClassNameSchool($user_id) {
        $subscribe = Subscription::where('usr_id',operator: $user_id)->latest("inscrip_id")->first();
        if($subscribe) return $subscribe->classSchool->class_name ?? null;
        else return null;
    }
}
if (! function_exists('getPensionClassSchool')) {
    function getPensionClassSchool($id) {
        $subscribe = Subscription::where('inscrip_id',operator: $id)->latest(column: "inscrip_id")->first();
        if($subscribe) return $subscribe->classSchool->class_pension ?? 0;
        else return 0;
    }
}
if (! function_exists('getClassNameById')) {
    function getClassNameById($class_id) {
        $class = ClassSchool::where('class_id',$class_id)->first();
        if($class) return $class->class_name ?? null;
        else return null;
    }
}
if (! function_exists(function: 'getLastYear')) {
    function getLastYear() {
        $year = Year::latest("annee_id")->first();
        if($year) return $year->annee_date ?? null;
        else return null;
    }
}
if (! function_exists('getDataPension')) {
    function getDataPension($inscription_id) {
        $pension = Pension::where('inscrip_id',$inscription_id)->latest(column: "pen_id")->get();
        if($pension) return $pension;
        else return null;
    }
}
if (! function_exists('getSumPension')) {
    function getSumPension($inscription_id, $date_limite = null) {
        $query = Pension::where('inscrip_id', $inscription_id);

        // Si une date est passée, on limite les paiements jusqu'à cette date incluse
        if (!empty($date_limite)) {
            $query->whereDate('pen_date', '<=', $date_limite);
        }

        // Ici on additionne bien le montant payé (ex: pen_amount)
        $pension = $query->sum("pen_montant");

        return $pension ?: 0;
    }
}
if (! function_exists('calculateAffairs')) {
    function calculateAffairs($type)
    {
        $currentDate = date('Y-m-d');
        $data = CustomerAffair::get();
        $count = 0;
        $weekStartDate = Carbon::now()->subDays(7)->format('Y-m-d');

        foreach ($data as $value) {
            $registrationDate = strtotime($value->ca_date);
            $dayRegistrationDate = date('Y-m-d', $registrationDate);
            $monthRegistrationDate = date('Y-m', $registrationDate);
            $yearRegistrationDate = date('Y', $registrationDate);

            switch ($type) {
                case "toDay":
                    if ($currentDate == $dayRegistrationDate) {
                        $count++;
                    }
                    break;
                case "month":
                    if (date('Y-m', strtotime($currentDate)) == $monthRegistrationDate) {
                        $count++;
                    }
                    break;
                case "year":
                    if (date('Y', strtotime($currentDate)) == $yearRegistrationDate) {
                        $count++;
                    }
                    break;
                case 'last_7_day':
                    if (Carbon::parse($registrationDate)->greaterThanOrEqualTo($weekStartDate)) {
                        $count++;
                    }
                    break;
                case "all":
                    $count++;
                    break;
                case "lastYear":
                    $lastYear = date('Y', strtotime('-1 year'));
                    if (date('Y', strtotime($currentDate)) == $lastYear) {
                        $count++;
                    }
                    break;
                case "active":
                    if ($value->ca_status == 1) {
                        $count++;
                    }
                    break;
                case "inactive":
                    if ($value->ca_status == 0) {
                        $count++;
                    }
                    break;
                default:
                    $count = 0;
            }
        }

        return $count;
    }

}
if (! function_exists('calculateStudents')) {
    function calculateStudents($type)
    {
        $currentDate = date('Y-m-d');
        $data = User::get();
        $count = 0;
        $weekStartDate = Carbon::now()->subDays(7)->format('Y-m-d');

        foreach ($data as $value) {
            $registrationDate = strtotime($value->date_reg);
            $dayRegistrationDate = date('Y-m-d', $registrationDate);
            $monthRegistrationDate = date('Y-m', $registrationDate);
            $yearRegistrationDate = date('Y', $registrationDate);
            if($value->usr_status == 1){
                switch ($type) {
                    case "toDay":
                        if ($currentDate == $dayRegistrationDate) {
                            $count++;
                        }
                        break;
                    case "month":
                        if (date('Y-m', strtotime($currentDate)) == $monthRegistrationDate) {
                            $count++;
                        }
                        break;
                    case "year":
                        if (date('Y', strtotime($currentDate)) == $yearRegistrationDate) {
                            $count++;
                        }
                        break;
                    case 'last_7_day':
                        if (Carbon::parse($registrationDate)->greaterThanOrEqualTo($weekStartDate)) {
                            $count++;
                        }
                        break;
                    case "all":
                        $count++;
                        break;
                    case "lastYear":
                        $lastYear = date('Y', strtotime('-1 year'));
                        if (date('Y', strtotime($currentDate)) == $lastYear) {
                            $count++;
                        }
                        break;
                    default:
                        $count = 0;
                }
            }
        }

        return $count;
    }

}
if (! function_exists('getPensionByTypeOld')) {
    function getPensionByTypeOld($type) {
        $amount = 0;
        $currentDate = date('Y-m-d');
        $weekStartDate = Carbon::now()->subDays(7)->format('y-m-d');
        $data = Pension::get();
        if (isset($data) && count($data) > 0) {
            foreach ($data as $key => $value) {
                $created_at = Carbon::parse($value->pen_date)->format('y-m-d');
                $amountExpense = $value->pen_montant;
                $fineDate = strtotime($created_at);

                $dayfineDate = date('Y-m-d', $fineDate);
                $monthfineDate = date('Y-m', $fineDate);
                $yearfineDate = date('Y', $fineDate);

                // if($value->am_status == 1) {
                    switch ($type) {
                        case 'toDay':
                            if (date('Y-m-d', strtotime($currentDate)) == $dayfineDate) {
                                $amount += $amountExpense;
                            }
                            break;

                        case 'last_7_day':
                            if (Carbon::parse($fineDate)->greaterThanOrEqualTo($weekStartDate)) {
                                $amount += $amountExpense;
                            }
                            break;

                        case 'month':
                            if (date('Y-m', strtotime($currentDate)) == $monthfineDate) {
                                $amount += $amountExpense;
                            }
                            break;

                        case 'year':
                            if (date('Y', strtotime($currentDate)) == $yearfineDate) {
                                $amount += $amountExpense;
                            }
                            break;
                        case "lastYear":
                            $lastYear = date('Y', strtotime('-1 year'));
                            if (date('Y', strtotime($currentDate)) == $lastYear) {
                                $amount += $amountExpense;
                            }
                            break;
                        default:
                            $amount = 0;
                    }
                // }
            }
        }

        return convert_amount_v2($amount);
    }

}

if (!function_exists('getPensionByType')) {
    function getPensionByType($type) {
        $amount = 0;
        $currentDate = Carbon::today();
        $weekStartDate = Carbon::now()->subDays(7);
        $pensions = Pension::all();

        if ($pensions->isNotEmpty()) {
            foreach ($pensions as $pension) {
                $penDate = Carbon::parse($pension->pen_date);
                $amountExpense = $pension->pen_montant;

                switch ($type) {
                    case 'toDay':
                        if ($penDate->isSameDay($currentDate)) {
                            $amount += $amountExpense;
                        }
                        break;

                    case 'last_7_day':
                        if ($penDate->greaterThanOrEqualTo($weekStartDate)) {
                            $amount += $amountExpense;
                        }
                        break;

                    case 'month':
                        if ($penDate->isSameMonth($currentDate) && $penDate->year == $currentDate->year) {
                            $amount += $amountExpense;
                        }
                        break;

                    case 'year':
                        if ($penDate->isSameYear($currentDate)) {
                            $amount += $amountExpense;
                        }
                        break;

                    case 'lastYear':
                        $lastYear = $currentDate->subYear()->year;
                        if ($penDate->year == $lastYear) {
                            $amount += $amountExpense;
                        }
                        break;

                    default:
                        $amount = 0;
                        break;
                }
            }
        }

        return convert_amount_v2($amount);
    }
}


if (!function_exists('fetchResponseByValue')) {
    function fetchResponseByValue($value) {
        $message = "";

        if ($value === "0") {
            $message = "Prémière Tranche en cours";
        } elseif ($value === "1") {
            $message = "Prémière Tranche Terminée";
        } elseif ($value === '1-1') {
            $message = "Deuxième Tranche en cours";
        } elseif ($value === '1-2') {
            $message = "Deuxième Tranche Terminée";
        } elseif ($value === '1-2-2') {
            $message = "Troisième Tranche en cours";
        } elseif ($value === '1-2-3') {
            $message = "Troisième Tranche Terminée";
        } else {
            $message = "Tranche Inconnue";
        }

        return $message;
    }
}
if (!function_exists('fetchResponseByValueV2')) {
    function fetchResponseByValueV2($value) {
        $message = "";

        if ($value === "0") {
            $message = "Prémière Tranche";
        } elseif ($value === "1") {
            $message = "Prémière Tranche";
        } elseif ($value === '1-1') {
            $message = "Deuxième Tranche";
        } elseif ($value === '1-2') {
            $message = "Deuxième Tranche";
        } elseif ($value === '1-2-2') {
            $message = "Troisième Tranche";
        } elseif ($value === '1-2-3') {
            $message = "Troisième Tranche";
        } else {
            $message = "Tranche Inconnue";
        }

        return $message;
    }
}
if (!function_exists('ordinal_fr')) {

    function ordinal_fr($number)
    {
        if (!is_numeric($number)) {
            return $number;
        }

        if ($number == 1) {
            return $number . '<sup>ère</sup>';
        }

        return $number . '<sup>ème</sup>';
    }
}
if (!function_exists('ordinal_en')) {
    function ordinal_en($number)
    {
        if (!is_numeric($number)) {
            return $number;
        }

        $number = intval($number);
        $suffix = 'th';

        // Exceptions pour 11, 12, 13
        if (!in_array(($number % 100), [11, 12, 13])) {
            switch ($number % 10) {
                case 1: $suffix = 'st'; break;
                case 2: $suffix = 'nd'; break;
                case 3: $suffix = 'rd'; break;
            }
        }

        return $number . '<sup>' . $suffix . '</sup>';
    }
}
if (!function_exists('getAppreciationGenerale')) {
    function getAppreciationGenerale($moyenneGenerale, $classCycle = 'FRANCOPHONE')
    {
        if (!is_numeric($moyenneGenerale)) {
            return '-';
        }

        // 🇫🇷 Français
        $appreciationsFr = [
            'excellent'   => 'Excellent',
            'tres_bien'   => 'Très bien',
            'bien'        => 'Bien',
            'assez_bien'  => 'Assez bien',
            'passable'      => 'Passable',
            'insuffisant' => 'Insuffisant',
        ];

        // 🇬🇧 Anglais
        $appreciationsEn = [
            'excellent'   => 'Excellent',
            'tres_bien'   => 'Very Good',
            'bien'        => 'Good',
            'assez_bien'  => 'Fairly Good',
            'passable'      => 'Average',
            'insuffisant' => 'Insufficient',
        ];

        // Sélection du dictionnaire selon la session
        $dict = strtoupper($classCycle) == 'ANGLOPHONE' ? $appreciationsEn : $appreciationsFr;

        // Logique d'appréciation
        if ($moyenneGenerale >= 18) {
            return $dict['excellent'];
        } elseif ($moyenneGenerale >= 16) {
            return $dict['tres_bien'];
        } elseif ($moyenneGenerale >= 14) {
            return $dict['bien'];
        } elseif ($moyenneGenerale >= 12) {
            return $dict['assez_bien'];
        } elseif ($moyenneGenerale >= 10) {
            return $dict['passable'];
        } else {
            return $dict['insuffisant'];
        }
    }
}
if (!function_exists('getRatingGenerale')) {
    function getRatingGenerale($moyenneGenerale, $classCycle = 'FRANCOPHONE')
    {
        if (!is_numeric($moyenneGenerale)) {
            return '-';
        }

        // 🇫🇷 Français
        $appreciationsFr = [
            '1'     => 'A+',
            '2'     => 'A',
            '3'     => 'ECA',
            '4'     => 'CNA',
        ];

        // 🇬🇧 Anglais
        $appreciationsEn = [
            '1'     => 'A+',
            '2'     => 'A',
            '3'     => 'CPA',
            '4'     => 'NA',
        ];

        // Sélection du dictionnaire selon la session
        $dict = strtoupper($classCycle) == 'ANGLOPHONE' ? $appreciationsEn : $appreciationsFr;

        // Logique d'appréciation
        if ($moyenneGenerale >= 16) {
            return $dict['1'];
        } elseif ($moyenneGenerale >= 14) {
            return $dict['2'];
        } elseif ($moyenneGenerale >= 10) {
            return $dict['3'];
        }else {
            return $dict['4'];
        }
    }
}

if (!function_exists('getStudentsWithRank')) {
    function getStudentsWithRank($student, $classId, $session, $sequence, $langType = null)
    {
        $query = StudentRank::where('class_id', $classId)
                ->where('session', $session)
                ->where('sequence', $sequence)
                ->where('usr_id', $student);

        // Si lang_type est spécifié, filtrer par langue
        if ($langType) {
            $query->where('lang_type_rank', $langType);
        } else {
            // Pour les systèmes unilingues, prendre le rang sans langue
            $query->whereNull('lang_type_rank');
        }

        return $query->first();
    }
}
if (!function_exists('getStudentsWithRankAllOld')) {
    function getStudentsWithRankAllOld($classId, $session, $sequence)
    {
        // Récupérer les étudiants avec leurs notes pour la session et séquence spécifiques
        $students = User::with(['subscription' => function($q) use ($classId, $session) {
                $q->where('class_id', $classId)
                  ->where('inscrip_annee', $session);
            }, 'notes' => function($q) use ($classId, $session, $sequence) {
                $q->where('class_id', $classId)
                  ->where('note_annee', $session)
                  ->where('trim_id', $sequence);
            }, 'notes.sousMatiere'])
            ->whereHas('subscription', function($q) use ($classId, $session) {
                $q->where('class_id', $classId)
                  ->where('inscrip_annee', $session);
            })
            ->get()
            ->filter(function($student) {
                return $student->subscription !== null;
            });

        $studentsData = [];

        foreach ($students as $student) {
            $totalNote = 0;
            $totalBareme = 0;
            $subjectsWithNotes = 0;

            foreach ($student->notes as $note) {
                if ($note->note_s_mat_usr !== null && $note->sousMatiere) {
                    $totalNote += $note->note_s_mat_usr;
                    $totalBareme += $note->sousMatiere->s_mat_bareme_max ?? 20;
                    $subjectsWithNotes++;
                }
            }

            // Éviter la division par zéro
            $moyenneGenerale = $totalBareme > 0 ? ($totalNote / $totalBareme) * 20 : 0;

            $studentsData[] = [
                'student' => $student,
                'totalPoints' => $totalNote,
                'totalBareme' => $totalBareme,
                'moyenneGenerale' => $moyenneGenerale,
                'subjectsWithNotes' => $subjectsWithNotes,
                'formattedTotal' => $totalNote . '/' . $totalBareme,
                'formattedAverage' => number_format($moyenneGenerale, 2) . '/20'
            ];
        }

        // Trier par moyenne générale décroissante
        usort($studentsData, function($a, $b) {
            return $b['moyenneGenerale'] <=> $a['moyenneGenerale'];
        });

        // Calcul des rangs avec gestion des ex-aequo
        $rank = 1;
        $previousAverage = null;
        $sameRankCount = 0;

        foreach ($studentsData as $index => &$studentData) {
            if ($previousAverage !== null && abs($studentData['moyenneGenerale'] - $previousAverage) < 0.01) {
                // Même moyenne = même rang
                $sameRankCount++;
            } else {
                // Nouvelle moyenne = nouveau rang
                $rank += $sameRankCount;
                $sameRankCount = 0;
            }
            
            $studentData['rank'] = $rank;
            $previousAverage = $studentData['moyenneGenerale'];
            
            // Préparer le rang suivant
            if ($sameRankCount == 0) {
                $rank++;
            }
        }

        return $studentsData;
    }
}

if (!function_exists('getStudentsWithRankAll')) {
    function getStudentsWithRankAll($classId, $session, $sequence, $langType = null)
    {
        // Récupérer les étudiants avec leurs notes pour la session et séquence spécifiques
        $students = User::with(['subscription' => function($q) use ($classId, $session) {
                $q->where('class_id', $classId)
                  ->where('inscrip_annee', $session);
            }, 'notes' => function($q) use ($classId, $session, $sequence) {
                $q->where('class_id', $classId)
                  ->where('note_annee', $session)
                  ->where('trim_id', $sequence);
            }, 'notes.sousMatiere', 'notes.competence']) // Ajouter la relation competence
            ->whereHas('subscription', function($q) use ($classId, $session) {
                $q->where('class_id', $classId)
                  ->where('inscrip_annee', $session);
            })
            ->get()
            ->filter(function($student) {
                return $student->subscription !== null;
            });

        $studentsData = [];

        foreach ($students as $student) {
            $totalNote = 0;
            $totalBareme = 0;
            $subjectsWithNotes = 0;

            foreach ($student->notes as $note) {
                if ($note->note_s_mat_usr !== null && $note->sousMatiere && $note->competence) {
                    
                    // FILTRER PAR TYPE DE LANGUE (basé sur competence.lang_type)
                    $shouldInclude = false;
                    
                    if ($langType === 'FR') {
                        // Inclure seulement les compétences françaises
                        $shouldInclude = $note->competence->lang_type !== 'EN';
                    } elseif ($langType === 'EN') {
                        // Inclure seulement les compétences anglaises
                        $shouldInclude = $note->competence->lang_type === 'EN';
                    } else {
                        // Pas de filtre - inclure toutes les compétences
                        $shouldInclude = true;
                    }

                    if ($shouldInclude) {
                        $totalNote += $note->note_s_mat_usr;
                        $totalBareme += $note->sousMatiere->s_mat_bareme_max ?? 20;
                        $subjectsWithNotes++;
                    }
                }
            }

            // Éviter la division par zéro
            $moyenneGenerale = $totalBareme > 0 ? ($totalNote / $totalBareme) * 20 : 0;

            $studentsData[] = [
                'student' => $student,
                'totalPoints' => $totalNote,
                'totalBareme' => $totalBareme,
                'moyenneGenerale' => $moyenneGenerale,
                'subjectsWithNotes' => $subjectsWithNotes,
                'formattedTotal' => $totalNote . '/' . $totalBareme,
                'formattedAverage' => number_format($moyenneGenerale, 2) . '/20'
            ];
        }

        // Trier par moyenne générale décroissante
        usort($studentsData, function($a, $b) {
            return $b['moyenneGenerale'] <=> $a['moyenneGenerale'];
        });

        // Calcul des rangs avec gestion des ex-aequo
        $rank = 1;
        $previousAverage = null;
        $sameRankCount = 0;

        foreach ($studentsData as $index => &$studentData) {
            if ($previousAverage !== null && abs($studentData['moyenneGenerale'] - $previousAverage) < 0.01) {
                // Même moyenne = même rang
                $sameRankCount++;
            } else {
                // Nouvelle moyenne = nouveau rang
                $rank += $sameRankCount;
                $sameRankCount = 0;
            }
            
            $studentData['rank'] = $rank;
            $previousAverage = $studentData['moyenneGenerale'];
            
            // Préparer le rang suivant
            if ($sameRankCount == 0) {
                $rank++;
            }
        }

        return $studentsData;
    }
}



if (!function_exists('ordinalRank')) {

    /**
     * Retourne le rang avec ordinal en FR ou EN, en tenant compte du sexe pour le 1er.
     *
     * @param int $rank
     * @param string $lang 'FRANCOPHONE' ou 'ANGLOPHONE'
     * @param string|null $gender 'M' ou 'F' (pour français)
     * @return string
     */
    function ordinalRank(int $rank, string $lang = 'FRANCOPHONE', ?string $gender = null): string
    {
        if ($lang === 'FRANCOPHONE') {
            if ($rank == 1) {
                return $gender === 'F' ? '1<sup>ère</sup>' : '1<sup>er</sup>';
            }
            return $rank . '<sup>ème</sup>';
        } 

        if ($lang === 'ANGLOPHONE') {
            if ($rank == 1) return '1<sup>st</sup>';
            if ($rank == 2) return '2<sup>nd</sup>';
            if ($rank == 3) return '3<sup>rd</sup>';
            return $rank . '<sup>th</sup>';
        }

        return (string)$rank;
    }
}


if (!function_exists('lastDateOfTranche')) {
    function lastDateOfTranche($value) {
        $date = "";
        $year = date('Y');
        if ($value === "first") {
            $date = $year."-09-30";
        } elseif ($value === "second") {
            $date = $year."-11-30";
        } elseif ($value === 'third') {
            $date = $year."-01-30";
        } else {
            $date = date('Y-m-d');
        }

        return Carbon::parse($date)->format('Y-m-d');
    }
}
if (!function_exists('translateDate')) {
    function translateDate($date, $lang)
    {
        if ($lang == 'fr') {
            Carbon::setLocale('fr');
        } else {
            Carbon::setLocale('en');
        }

        $carbonDate = Carbon::parse($date);

        $formattedDate = $carbonDate->translatedFormat('l j F Y');

        return $formattedDate;
    }
}
if (!function_exists('translateCycle')) {
    function translateCycle($cycle)
  