<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 Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

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('normalizePresenceDates')) {
    function normalizePresenceDates() {
        $presences = DB::table('presences')
            ->select('p_id', 'p_date')
            ->whereNotNull('p_date')
            ->get();

        foreach ($presences as $presence) {
            try {
                $newDate = Carbon::parse($presence->p_date)->format('Y-m-d');
                DB::table('presences')
                    ->where('p_id', $presence->p_id)
                    ->update(['p_date' => $newDate]);
            } catch (\Exception $e) {
                Log::warning("Impossible de parser la date pour l'id {$presence->p_id}: {$presence->p_date}");
            }
        }
        return "Toutes les dates ont été normalisées au format Y-m-d.";
    }
}

if (! function_exists('convert_number')) {
    function convert_number($amount) {
        if (is_numeric($amount)) {
            return number_format($amount, 2, ',',' ');
        }
        return 0;
    }
}

if (! function_exists('getConfigurationValue')) {
    function getConfigurationValue($key, $default = null) {
        try {
            $config = DB::table('configurations')
                ->where('status', 1)
                ->first();
            
            return $config->$key ?? $default;
        } catch (\Exception $e) {
            Log::error("Erreur lors de la récupération de la configuration: " . $e->getMessage());
            return $default;
        }
    }
}

if (! function_exists('setConfigurationValue')) {
    function setConfigurationValue($key, $value) {
        try {
            $config = DB::table('configurations')
                ->where('status', 1)
                ->first();

            if ($config) {
                DB::table('configurations')
                    ->where('id', $config->id)
                    ->update([$key => $value]);
            } else {
                // Créer une nouvelle configuration active
                $data = [$key => $value, 'status' => 1, 'date_reg' => now()];
                DB::table('configurations')->insert($data);
            }
            
            return true;
        } catch (\Exception $e) {
            Log::error("Erreur lors de la mise à jour de la configuration: " . $e->getMessage());
            return false;
        }
    }
}

if (! function_exists('getHoursByType')) {
    function getHoursByType(string $type): string {
        switch($type) {
            case 'arrived':
                return getConfigurationValue('arrived', '08:30');
            case 'arrived_am':
                return getConfigurationValue('arrived_am', '08:30 AM');
            case 'depart':
                return getConfigurationValue('depart', '15:30');
            case 'depart_pm':
                return getConfigurationValue('depart_pm', '15:30 PM');
            default:
                return 'Type invalide';
        }
    }
}

if (! function_exists('getLogo')) {
    function getLogo() {
        $logo = getConfigurationValue('logo');
        if ($logo) {
            return asset($logo);
        }
        // return asset('logo/pev.png');
    }
}

if (! function_exists('getNameCabinet')) {
    function getNameCabinet() {
        return getConfigurationValue('name', 'SYGEIP PRO');
    }
}

if (! function_exists('getCardRecto')) {
    function getCardRecto() {
        return getConfigurationValue('card_recto');
    }
}

if (! function_exists('getCardVerso')) {
    function getCardVerso() {
        return getConfigurationValue('card_verso');
    }
}

if (! function_exists('getUrlImage')) {
    function getUrlImage() {
        return getConfigurationValue('url_image');
    }
}

if (! function_exists('getUrlImageOthers')) {
    function getUrlImageOthers() {
        return getConfigurationValue('url_image_others');
    }
}
if (! function_exists('getDaysWork')) {
    function getDaysWork() {
        return getConfigurationValue('days_work');
    }
}
if (! function_exists('getCardColor')) {
    function getCardColor() {
        return getConfigurationValue('card_color');
    }
}

if (! function_exists('getFetchImage')) {
    function getFetchImage($image) {
        $baseUrl = getUrlImage();
        if (!$baseUrl) {
            $baseUrl = "https://pia-soft.com/sygeip_pev/images/";
        }
        return $baseUrl . $image;
    }
}

if (! function_exists('getFetchImageOthers')) {
    function getFetchImageOthers($image) {
        $baseUrl = getUrlImageOthers();
        if (!$baseUrl) {
            $baseUrl = "https://pia-soft.com/sygeip_pev/img_autres/";
        }
        return $baseUrl . $image;
    }
}

if (! function_exists('getPersonnelImage')) {
    function getPersonnelImage($image, $default = 'user.png') {
        // Si aucune image n'est fournie, retourner l'image par défaut
        if (empty($image) || $image === 'null' || $image === 'undefined') {
            return asset($default);
        }
        
        // Vérifier si c'est une URL complète
        if (filter_var($image, FILTER_VALIDATE_URL)) {
            return $image;
        }
        
        // Vérifier si c'est un chemin local
        if (file_exists(public_path($image))) {
            return asset($image);
        }
        
        // Utiliser l'URL de base des images du personnel
        $baseUrl = getUrlImage();
        if (!$baseUrl) {
            $baseUrl = "https://pia-soft.com/sygeip_pev/images/";
        }
        
        // Retourner l'URL complète de l'image
        return $baseUrl . $image;
    }
}

if (! function_exists('getPersonnelImageOrDefault')) {
    function getPersonnelImageOrDefault($image, $default = 'user.png') {
        $imageUrl = getPersonnelImage($image, $default);
        
        // Vérifier si l'image existe (pour les URLs externes, on suppose qu'elle existe)
        if (filter_var($imageUrl, FILTER_VALIDATE_URL) && !str_contains($imageUrl, asset(''))) {
            return $imageUrl;
        }
        
        // Pour les assets locaux, vérifier si le fichier existe
        $localPath = str_replace(asset(''), '', $imageUrl);
        if (file_exists(public_path($localPath))) {
            return $imageUrl;
        }
        
        // Retourner l'image par défaut si l'image n'existe pas
        return asset($default);
    }
}

if (!function_exists('formatPresenceType')) {
    function formatPresenceType($type) {
        if ($type === 'AM') {
            return 'Entrée';
        } elseif ($type === 'PM') {
            return 'Sortie';
        } elseif ($type === 'PAUSE') {
            return 'Pause';
        } elseif ($type === 'AM-PM') {
            return 'Entrée / Sortie';
        }
        return $type ?: 'Tous';
    }
}

if (!function_exists('convertTo24Hour')) {
   function convertTo24Hour($time12h) {
        try {
            $time = Carbon::createFromFormat('h:i:s A', $time12h);
            return $time->format('H:i:s');
        } catch (\Exception $e1) {
            try {
                $time = Carbon::createFromFormat('h:i A', $time12h);
                return $time->format('H:i');
            } catch (\Exception $e2) {
                return $time12h;
            }
        }
    }
}

if (!function_exists('getArrivalStatus')) {
    function getArrivalStatus($arrivalTime, $referenceTime = null) {
        $referenceTime = $referenceTime ?: getHoursByType('arrived');
        
        $arrival = Carbon::createFromFormat('H:i', $arrivalTime);
        $reference = Carbon::createFromFormat('H:i', $referenceTime);

        return $arrival->lessThanOrEqualTo($reference) ? 'À l\'heure' : 'En retard';
    }
}

if (!function_exists('getArrivalStatusWithMeridian')) {
    function getArrivalStatusWithMeridian($arrivalTime) {
        try {
            $arrivalTime = trim($arrivalTime);
            $referenceTime = trim(getHoursByType('arrived_am'));
            
            $arrivalTimestamp = strtotime($arrivalTime);
            $referenceTimestamp = strtotime($referenceTime);
            
            if ($arrivalTimestamp === false) {
                throw new \Exception("Heure d'arrivée invalide: $arrivalTime");
            }
            
            if ($referenceTimestamp === false) {
                throw new \Exception("Heure de référence invalide: $referenceTime");
            }
            
            return $arrivalTimestamp <= $referenceTimestamp ? 'À l\'heure' : 'En retard';
            
        } catch (\Exception $e) {
            Log::error("Erreur dans getArrivalStatusWithMeridian: " . $e->getMessage());
            return 'Erreur';
        }
    }
}

if (!function_exists('isExpired')) {
    function isExpired($date) {
        $givenDate = $date instanceof Carbon ? $date : Carbon::parse($date);
        $today = Carbon::today();
        return $givenDate->lt($today);
    }
}

if (!function_exists('checkExpiration')) {
    function checkExpiration($date, $includeTime = false) {
        $givenDate = $date instanceof Carbon ? $date : Carbon::parse($date);
        $now = $includeTime ? Carbon::now() : Carbon::today();
        
        return [
            'is_expired' => $givenDate->lt($now),
            'is_today' => $givenDate->isSameDay($now),
            'is_future' => $givenDate->gt($now),
            'days_until_expiry' => $now->diffInDays($givenDate, false),
            'human_readable' => $givenDate->diffForHumans($now)
        ];
    }
}

if (! function_exists('getFolderTypes')) {
    function getFolderTypes() {
        return [
            'cv' => 'CV',
            'integration_act' => 'Acte d\'intégration',
            'work_contract' => 'Contrat de travail',
            'internship_agreement' => 'Accord de stage',
            'service_start_attestation' => 'Attestation de prise de service',
            'appointment_act' => 'Acte de nomination',
            'assignment_act' => 'Acte d\'affectation',
            'effective_presence_attestation' => 'Attestation de présence effective',
            'distinctions_prizes' => 'Distinction et prix',
            'sanctions' => 'Sanctions',
            'diplomas_certificates' => 'Diplômes et certificats',
            'cni' => 'CNI',
            'birth_certificate' => 'Acte de naissance',
            'marriage_certificate' => 'Acte de mariage',
            'ice_form' => 'Formulaire ICE'
        ];
    }
}

if (! function_exists('getFolderTypeName')) {
    function getFolderTypeName($type) {
        $types = getFolderTypes();
        return $types[$type] ?? $type;
    }
}

if (! function_exists('generateFolderOptions')) {
    function generateFolderOptions($selected = '') {
        $options = '<option value="">Sélectionnez un type</option>';
        
        foreach (getFolderTypes() as $value => $label) {
            $isSelected = $selected === $value ? 'selected' : '';
            $options .= '<option value="' . $value . '" ' . $isSelected . '>' . $label . '</option>';
        }
        
        return $options;
    }
}

if (! function_exists('insertConfiguration')) {
    function insertConfiguration($data) {
        try {
            // Vérifier si une configuration active existe déjà
            $existing = DB::table('configurations')->where('status', 1)->first();
            
            if ($existing) {
                // Désactiver l'ancienne configuration
                DB::table('configurations')->where('status', 1)->update(['status' => 0]);
            }
            
            // Préparer les données avec les valeurs par défaut
            $defaultData = [
                'status' => 1,
                'date_reg' => now()
            ];
            
            $insertData = array_merge($defaultData, $data);
            
            // Insérer la nouvelle configuration
            $id = DB::table('configurations')->insertGetId($insertData);
            
            return $id;
            
        } catch (\Exception $e) {
            Log::error("Erreur lors de l'insertion de la configuration: " . $e->getMessage());
            return false;
        }
    }
}

if (! function_exists('updateConfiguration')) {
    function updateConfiguration($id, $data) {
        try {
            $data['date_reg'] = now();
            $result = DB::table('configurations')->where('id', $id)->update($data);
            return $result;
        } catch (\Exception $e) {
            Log::error("Erreur lors de la mise à jour de la configuration: " . $e->getMessage());
            return false;
        }
    }
}

if (! function_exists('getAllConfigurations')) {
    function getAllConfigurations() {
        return DB::table('configurations')
            ->orderBy('status', 'desc')
            ->orderBy('date_reg', 'desc')
            ->get();
    }
}

if (! function_exists('getActiveConfiguration')) {
    function getActiveConfiguration() {
        return DB::table('configurations')
            ->where('status', 1)
            ->first();
    }
}

if (!function_exists('calculateRetardMinutes')) {
    function calculateRetardMinutes($arrivalTime) {
        try {
            // Nettoyer et convertir l'heure d'arrivée
            $arrivalTime = trim($arrivalTime);
            
            // Si l'heure a des secondes, les enlever
            if (substr_count($arrivalTime, ':') == 2) {
                $parts = explode(':', $arrivalTime);
                $arrivalTime = $parts[0] . ':' . $parts[1];
            }
            
            // Convertir en format 24h si nécessaire
            $arrivalTime = convertTo24Hour($arrivalTime);
            
            $heureArrivee = Carbon::createFromFormat('H:i', $arrivalTime);
            $heureReference = Carbon::createFromFormat('H:i', getHoursByType('arrived'));
            
            // Si l'heure d'arrivée est avant l'heure de référence, retourner 0
            if ($heureArrivee->lte($heureReference)) {
                return 0;
            }
            
            return $heureArrivee->diffInMinutes($heureReference);
        } catch (\Exception $e) {
            return 0;
        }
    }
}

if (!function_exists('getRetardLevel')) {
    function getRetardLevel($retardMinutes) {
        if ($retardMinutes <= 0) {
            return ['color' => 'success', 'text' => 'Retard Très léger en seconde'];
        } elseif ($retardMinutes <= 15) {
            return ['color' => 'warning', 'text' => 'Retard léger'];
        } elseif ($retardMinutes <= 30) {
            return ['color' => 'danger', 'text' => 'Retard modéré'];
        } else {
            return ['color' => 'dark', 'text' => 'Retard important'];
        }
    }
}

if (!function_exists('calculateDaysOld')) {

    function calculateDaysOld($startDate, $endDate)
    {
        $start = Carbon::parse($startDate);
        $end = Carbon::parse($endDate);

        // Jours fériés fixes (à adapter selon ton pays)
        $holidays = [
            '01-01', // Nouvel an
            '02-11', // Fête de la Jeunesse
            '05-01', // Travail
            '05-20', // Unité nationale
            '08-15', // Assomption
            '10-01', // Réunification
            '12-25', // Noël
        ];

        $workingDaysPerWeek = getDaysWork();

        // Définir les jours ouvrés selon l'entreprise
        // 1 = lundi, 2 = mardi, 3 = mercredi, 4 = jeudi, 5 = vendredi, 6 = samedi
        $allowedWeekdays = ($workingDaysPerWeek == 6)
            ? [1, 2, 3, 4, 5, 6]  // Du lundi au samedi
            : [1, 2, 3, 4, 5];     // Du lundi au vendredi

        return $start->diffInDaysFiltered(function (Carbon $date) use ($holidays, $allowedWeekdays) {

            // Exclure les jours non travaillés
            if (!in_array($date->dayOfWeekIso, $allowedWeekdays)) {
                return false;
            }

            // Exclure les jours fériés
            if (in_array($date->format('m-d'), $holidays)) {
                return false;
            }

            return true;

        }, $end);
    }
}
if (!function_exists('isWorkingDay')) {

    function isWorkingDay(Carbon $date)
    {
        $daysWork = getDaysWork(); // 5 ou 6

        // Jours ouvrés selon config
        // $allowedWeekdays = ($daysWork === 6)
        //     ? [1, 2, 3, 4, 5, 6]   // Lun → Sam
        //     : [1, 2, 3, 4, 5];     // Lun → Ven

        $allowedWeekdays = range(1, $daysWork);
        
        // Jours fériés
        $holidays = [
            '01-01', // Nouvel an
            '02-11', // Fête de la Jeunesse
            '05-01', // Travail
            '05-20', // Unité nationale
            '08-15', // Assomption
            '10-01', // Réunification
            '12-25', // Noël
        ];

        // Exclure week-end non travaillé
        if (!in_array($date->dayOfWeekIso, $allowedWeekdays)) {
            return false;
        }

        // Exclure jour férié
        if (in_array($date->format('m-d'), $holidays)) {
            return false;
        }

        return true;
    }
}

if (!function_exists('calculateDays')) {

    function calculateDays($startDate, $endDate)
    {
        $start = Carbon::parse($startDate)->startOfDay();
        $end   = Carbon::parse($endDate)->startOfDay();

        // Toujours inclure le jour de départ
        // (Ex: 2025-02-01 → 2025-02-01 = 1 jour)
        if ($start->equalTo($end)) {
            return isWorkingDay($start) ? 1 : 0;
        }

        // Obtenir le nombre de jours ouvrés selon la configuration
        $workingDaysPerWeek = getDaysWork();

        // $allowedWeekdays = ($workingDaysPerWeek == 6)
        //     ? [1,2,3,4,5,6]  // Lun → Sam
        //     : [1,2,3,4,5];   // Lun → Ven

        $allowedWeekdays = range(1, $workingDaysPerWeek);

        $holidays = [
            '01-01', // Nouvel an
            '02-11', // Fête de la Jeunesse
            '05-01', // Travail
            '05-20', // Unité nationale
            '08-15', // Assomption
            '10-01', // Réunification
            '12-25', // Noël
        ];

        // Fonction interne pour identifier les jours travaillés
        $isWorkingDay = function (Carbon $date) use ($allowedWeekdays, $holidays) {
            if (!in_array($date->dayOfWeekIso, $allowedWeekdays)) return false;
            if (in_array($date->format('m-d'), $holidays)) return false;
            return true;
      