<?php

class debug
{

    private static $logs = [];
    private static $startTime;
    private static $closeTime;

    public static function addFileSubmit()
    {
        $myfile = fopen(DOCUMENT_ROOT . FILE_DEBUG_SUBMIT, "w");
        fclose($myfile);
    }

    public static function removeFileSubmit()
    {
        unlink(DOCUMENT_ROOT . FILE_DEBUG_SUBMIT);
    }

    public static function isSubmit()
    {
        return (file_exists(DOCUMENT_ROOT . FILE_DEBUG_SUBMIT)) ? TRUE : FALSE;
    }
    
    public static function includeDebug()
    {
        if (core::isDebug()) {
            echo '<link rel="stylesheet" href="css/debug.css">';
        }
    }

    public static function dump($var, $label = 'Dump', $echo = true)
    {
        // Start output buffering
        ob_start();

        echo "<pre class='debug-dump'>";
        echo "<strong>$label:</strong> ";

        // Convert array or object to string
        if (is_array($var)) {
            print_r($var);
        } elseif (is_object($var)) {
            echo self::objectToString($var);
        } else {
            var_dump($var);
        }

        echo "</pre>";

        // Get the contents of the buffer
        $output = ob_get_clean();

        // If echo is true, print the output
        if ($echo) {
            echo $output;
        } else {
            return $output;
        }
    }

    public static function objectToString($object, $_tab = NULL) {
        ob_start();

        $tab = "&nbsp;&nbsp;&nbsp;&nbsp;" . $_tab;
        
        echo "<span class='debug-console-capsule'>Object (" . get_class($object) . ")\n</span>";
        echo $_tab . "<span class='debug-console-capsule'>{\n</span>";
        
        foreach (get_object_vars($object) as $property => $value) {
            echo $tab . "<span class='debug-console-capsule'>[<span class='debug-console-key'>$property</span>] => </span>";
            if (is_array($value)) {
                echo self::arrayToString($value, $tab);
            } elseif (is_object($value)) {
                echo self::objectToString($value, $tab);
            } else {
                echo "<span class='debug-console-value'>" . var_export($value, true) . "</span>\n";
            }
        }
        
        echo $_tab . "<span class='debug-console-capsule'>}\n</span>";
        
        return ob_get_clean();
    }



    public static function arrayToString($array, $_tab = NULL)
    {
        ob_start();

        $tab = "&nbsp;&nbsp;&nbsp;&nbsp;".$_tab;
        
        echo "<span class='debug-console-capsule'>Array\n</span>";
        echo $_tab . "<span class='debug-console-capsule'>(\n</span>";
        
        foreach ($array as $key => $value) {
            echo $tab . "<span class='debug-console-capsule'>[<span class='debug-console-key'>$key</span>] => </span>";
            if (is_array($value)) {
                echo self::arrayToString($value, $tab);
            } elseif (is_object($value)) {
                echo self::objectToString($value, $tab);
            } else {
                echo "<span class='debug-console-value'>" . var_export($value, true) . "</span>\n";
            }
        }
        
        echo $_tab . "<span class='debug-console-capsule'>)\n</span>";
        
        return ob_get_clean();
    }

    private static function variableToString($var, $label)
    {
        ob_start();
        echo "$label: ";
        if (is_array($var) || is_object($var)) {
            print_r($var);
        } else {
            var_dump($var);
        }
        return ob_get_clean();
    }

    public static function getTraces(){
        $return = "Trace : ";
        
        // Obtenir la trace d'exécution
        $backtrace = debug_backtrace();
        $nb = count($backtrace)-1;

        for ($i=$nb; $i > 0; $i--) { 
            $return .= ($i != 0) ? "[".$backtrace[$i]["function"]."] " : NULL;
            $return .= str_replace(DOCUMENT_ROOT, '', $backtrace[$i]["file"]).":".$backtrace[$i]["line"];
            $return .= ($i != 1) ? " >> " : NULL;
        }

        return $return;
    }

    public static function log($_message, $_mark = NULL)
    {        
        $mark = "<div class='debug-head-console'>";
        $mark .= ($_mark != NULL) ? "<div style='font-weight: bold;'>". $_mark . "</div>" : NULL;
        $mark .= self::getTraces();
        $mark .= "</div>";
        if($_message != NULL) {
            if(is_array($_message)){
                self::$logs[] = $mark ."<div class='debug-console'>" . self::arrayToString($_message) . "</div>";
            } elseif(is_object($_message)){
                self::$logs[] = $mark ."<div class='debug-console'>" . self::objectToString($_message) . "</div>";
            } elseif($mark != NULL){
                self::$logs[] = $mark ."<div class='debug-console' style='color:blue;'>" . $_message . "</div>";
            } else {
                self::$logs[] = $_message;
            }
        }
    }

    public static function logSession($_message, $_mark = NULL)
    {        
        $mark = "<div class='debug-head-console'>";
        $mark .= ($_mark != NULL) ? "<div style='font-weight: bold;'>". $_mark . "</div>" : NULL;
        $mark .= self::getTraces();
        $mark .= "</div>";
        if($_message != NULL) {
            if(is_array($_message)){
                self::setSession($mark ."<div class='debug-console'>" . self::arrayToString($_message) . "</div>");
            } elseif(is_object($_message)){
                self::setSession($mark ."<div class='debug-console'>" . self::objectToString($_message) . "</div>");
            } elseif($mark != NULL){
                self::setSession($mark ."<div class='debug-console' style='color:blue;'>" . $_message . "</div>");
            } else {
                self::setSession($_message);
            }
        }
    }

    public static function renderLogs()
    {
        //if (!empty(self::$logs)) {

            echo "<div id='debugger-logs'>";

            echo "<div class='debug-renderLogs-header'>";
            echo "PHP ". phpversion() . " | " . number_format(self::$closeTime, 4) . " secondes ";
            echo "</div>";
            echo "<div class=\"form-check form-switch\">
                <input class=\"form-check-input\" type=\"checkbox\" id=\"checkIsSubmit\" " . core::checkboxSelecter(self::isSubmit(), 0) . " >
                <label class=\"form-check-label\" for=\"checkIsSubmit\">Intercepter la validation</label>
            </div>";

            foreach (self::$logs as $log) {
                echo ($log != NULL) ? "<div class='debug-renderLogs-print'>".nl2br($log)."</div>" : NULL;
            }

            if(self::ifSession()){
                foreach (self::getSession() as $logSession) {
                    echo ($logSession != NULL) ? "<div class='debug-renderLogs-print'>".nl2br($logSession)."</div>" : NULL;
                }
            }

            echo "</div>";

            echo "
            <script>
                $(document).ready(function() {

                    $('#checkIsSubmit').on('change', function() {
                        window.location.href = '/submit.php?from=parametres-debug-submit-activation&actif=' + $('#checkIsSubmit').prop('checked');
                    });
            
                    $('.toggle-logs').click(function() {
                        $('#debugger-logs').slideToggle();
                    });

                    // Apply syntax highlighting to log entries
                    $('.log-entry').each(function() {
                        var html = $(this).html();
                        html = html.replace(/(\\$\\w+)/g, '<span class=\"variable\">$1</span>');
                        html = html.replace(/(\\bfunction\\b)/g, '<span class=\"function\">$1</span>');
                        $(this).html(html);
                    });
                });
            </script>
        ";
        //}
    }

    public static function init()
    {
        // Register shutdown function to render logs at the end of the script execution
        register_shutdown_function(function () {
            self::renderLogs();
        });
    }

    public static function startTimer()
    {
        self::$startTime = microtime(true);
    }

    public static function endTimer()
    {
        self::$closeTime = microtime(true) - self::$startTime;
    }

    public static function getBadge(string $_link,string $_label){
        return '<a href="'. $_link .'" target="_blank" class="badge debug-badge">'. $_label .'</a>';
    }

    public static function printEnvironnement(){
        echo (ENVIRONNEMENT != "PROD") ? " [" . ENVIRONNEMENT . "]" : NULL;
    }

    public static function printBadges(){

        if(core::isMaintenance()){
            echo "<a href=\"/parametsres.html\"><span class=\"badge\" style=\"background-color:red; margin:5px;\">SITE EN MODE MAINTENANCE</span></a>";
        }
    
        if(core::isDebug()){
            echo "<a href=\"#\"><span class=\"badge toggle-logs\" style=\"background-color:orange; color:black; margin:5px;\">MODE DEBUG</span></a>";
        } 
    
        if(self::isSubmit()){
            echo "<a href=\"#\"><span class=\"badge toggle-logs\" style=\"background-color:orange; color:black; margin:5px;\">MODE DEBUG SUBMIT</span></a>";
        } 
    }

    public static function setSession($_data){
        $_SESSION["DEBUG"][] = $_data;
    }

    public static function getSession(){
        $return = $_SESSION["DEBUG"];
        self::resetSession();
        return $return;
    }

    public static function ifSession(){
        return empty($_SESSION["DEBUG"]) ? FALSE : TRUE;
    }

    public static function resetSession(){
        unset($_SESSION["DEBUG"]);
    }
}
