<?php

class ModelSettingDeveloperInfo extends Model
{

    public function getGeneralStatus()
    {
        $status_data = [];
        try {
            // SHOW GLOBAL STATUS
            $query = $this->db->query("SHOW GLOBAL STATUS");
            foreach ($query->rows as $row) {
                $status_data[$row['Variable_name']] = $row['Value'];
            }

            // Pegar a data e hora de último reinício do servidor MySQL
            $query = $this->db->query("SELECT FROM_UNIXTIME(UNIX_TIMESTAMP() - VARIABLE_VALUE) AS last_started
                                         FROM performance_schema.global_status
                                        WHERE VARIABLE_NAME = 'Uptime';");
            foreach ($query->rows as $row) {    
                $status_data['last_restart'] = $row['last_started'];
            }

            // Pegar a versao do MySQL
            $query = $this->db->query("SELECT mysql_version FROM sys.version;");
            foreach ($query->rows as $row) {    
                $status_data['Version'] = $row['mysql_version'];
            }

            // SHOW GLOBAL VARIABLES (para max_connections, por exemplo)
            $query = $this->db->query("SHOW GLOBAL VARIABLES LIKE 'max_connections';");
            if ($query->num_rows) {
                $status_data['max_connections'] = $query->row['Value'];
            }

            // Você pode adicionar mais variáveis globais que considere importantes
            $query = $this->db->query("SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';");
            if ($query->num_rows) {
                $status_data['Innodb_buffer_pool_size'] = $query->row['Value'];
            }

        } catch (\Throwable $e) {
            $status_data['error'] = "Erro ao coletar status geral: " . $e->getMessage();
            $logData = [
                'event'    => 'ModelSettingDeveloperInfo::getGeneralStatus',
                'message'  => 'DeveloperInfo Model Error (getGeneralStatus)',
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
        }
        return $status_data;
    }

    public function getProcessListDatabase()
    {
        $query = $this->db->query('SHOW FULL PROCESSLIST;');
        $process_list = [];
        if ($query->num_rows) {
            foreach ($query->rows as $row) {
                $process_list[] = [
                    'Id' => $row['Id'],
                    'User' => $row['User'],
                    'Host' => $row['Host'],
                    'db' => $row['db'],
                    'Command' => $row['Command'],
                    'Time' => $row['Time'],
                    'State' => $row['State'],
                    'Info' => $row['Info']
                ];
            }
        } else {
            $process_list = ['error' => 'Nenhum processo encontrado.'];
        }
        return $process_list;
    }

    public function getDatabaseSizes($database_name = null) 
    {
        $database_sizes = [];
        $where = '';
        if ($database_name) {
            $where = "where table_schema = '" . $this->db->escape(DB_DATABASE) . "'";
        }
        try {
            $query = $this->db->query("SELECT table_schema AS database_name,
                                           SUM(data_length + index_length) / 1024 / 1024 AS total_mb
                                    FROM information_schema.tables ". $where ."
                                    GROUP BY table_schema
                                    ORDER BY total_mb DESC;");
            $database_sizes = $query->rows;
        } catch (\Throwable $e) {
            $database_sizes['error'] = "Erro ao coletar tamanhos de banco de dados: " . $e->getMessage();
            $logData = [
                'event'    => 'ModelSettingDeveloperInfo::getDatabaseSizes',
                'message'  => 'DeveloperInfo Model Error (getDatabaseSizes)',
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
        }
        return $database_sizes;
    }

    public function getTopTablesBySize($database_name, $limit = 10) 
    {
        $top_tables = [];
        try {
            $query = $this->db->query("SELECT table_name,
                                              ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_mb
                                       FROM information_schema.tables
                                       WHERE table_schema = '" . $this->db->escape($database_name) . "'
                                       ORDER BY total_mb DESC
                                       LIMIT " . (int)$limit . ";");
            $top_tables = $query->rows;
        } catch (\Throwable $e) {
            $top_tables['error'] = "Erro ao coletar tabelas: " . $e->getMessage();
            $logData = [
                'event'    => 'ModelSettingDeveloperInfo::getTopTablesBySize',
                'message'  => 'DeveloperInfo Model Error (getTopTablesBySize)',
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
        }
        return $top_tables;
    }

    public function getIndexInfo($database_name) 
    {
        $index_info = [];
        try {
            $query = $this->db->query("SELECT table_name,
                                              COUNT(index_name) AS num_indexes,
                                              SUM(CASE WHEN non_unique = 0 THEN 1 ELSE 0 END) AS num_unique_indexes
                                        FROM information_schema.statistics
                                        WHERE table_schema = '" . $this->db->escape($database_name) . "'
                                        GROUP BY table_name
                                        ORDER BY num_indexes DESC;");
            $index_info = $query->rows;
        }
        catch (\Throwable $e) {
            $index_info['error'] = "Erro ao coletar informações de índices: " . $e->getMessage();
            $logData = [
                'event'    => 'ModelSettingDeveloperInfo::getIndexInfo',
                'message'  => 'DeveloperInfo Model Error (getIndexInfo)',
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
        }
        return $index_info;
    }
    public function getTableIndices($tableName) {
        $indices = [];
        try {
            $tableName = $this->db->escape($tableName);
            $query = $this->db->query("SHOW INDEX FROM `" . $tableName . "`;"); // Use backticks para nomes de tabela
            $indices = $query->rows;
        } catch (Exception $e) {
            $indices['error'] = "DeveloperInfo Model Error (getTableIndices for " . $tableName . "): " . $e->getMessage();
            $logData = [
                'event'    => 'ModelSettingDeveloperInfo::getTableIndices',
                'message'  => 'DeveloperInfo Model Error (getTableIndices for ' . $tableName . ')',
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
        }
        return $indices;
    }

    public function getFolderSizeRecursive($path, $limit = 307200, $topN = 10) {
        $maxSize = -1;
        $totalSize = 0;
        $fileCount = 0;
        $countLargest = 0;
        $allFiles = [];
        $largestFile = null;
        try {
            $iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
            );

            foreach ($iterator as $file) {
                if ($file->isFile()) {
                    $currentSize = $file->getSize();
                    $totalSize += $currentSize;
                    $fileCount++;

                    // Armazena o caminho e o tamanho do arquivo
                    $allFiles[] = [
                        'path' => $file->getPathname(),
                        'size' => $currentSize
                    ];

                    if ($currentSize > $limit) {
                        $countLargest++;
                    }
                }
            }
            usort($allFiles, function($a, $b) {
                return $b['size'] <=> $a['size'];
            });
            $topLargestFiles = array_slice($allFiles, 0, $topN);
            $largestFile = null;
            $maxSize = -1;
            if (!empty($topLargestFiles)) {
                $largestFile = $topLargestFiles[0]['path'];
                $maxSize = $topLargestFiles[0]['size'];
            }
            return [
                'tamanho_total' => $totalSize,
                'arquivos' => $fileCount,
                'maior_arquivo' => trim($largestFile),
                'tamanho_maior_arquivo' => $maxSize,
                'acima_limite' => $countLargest,
                'top_n_maiores_arquivos' => $topLargestFiles
            ];
        } catch (Exception $e) {
            $logData = [
                'event'    => 'ModelSettingDeveloperInfo::getFolderSizeRecursive',
                'message'  => 'DeveloperInfo Model Error (getFolderSizeRecursive)',
                'exception'=> [
                    'type'    => get_class($e),
                    'message' => $e->getMessage(),
                    'code'    => $e->getCode(),
                    'file'    => $e->getFile(),
                    'line'    => $e->getLine(),
                    'trace'   => $e->getTraceAsString()
                ],
                'datetime' => date('Y-m-d H:i:s'),
            ];
            $this->log->write(json_encode($logData, JSON_UNESCAPED_UNICODE));
            return [];
        }
    }

}