<?php

namespace App\Http\Controllers\Admin;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;

class SystemController extends Controller
{
    public function index(Request $request, array $params = []): void
    {
        $basePath = $this->app->basePath();

        $info = [
            'php_version'     => PHP_VERSION,
            'php_ok'          => version_compare(PHP_VERSION, '8.1.0', '>='),
            'extensions'      => $this->checkExtensions(),
            'writable_dirs'   => $this->checkWritableDirs($basePath),
            'db_status'       => $this->checkDatabase(),
            'installed'       => $this->app->isInstalled(),
            'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown',
            'active_theme'    => \App\Models\Setting::get('active_theme', 'default'),
            'disk_free'       => @disk_free_space('/'),
            'disk_total'      => @disk_total_space('/'),
        ];

        $this->renderAdmin('system/index', [
            'pageTitle' => __('admin.system.title'),
            'info'      => $info,
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
    }

    /**
     * Health-Check – visual admin page with system diagnostics.
     */
    public function healthCheck(Request $request, array $params = []): void
    {
        $basePath = $this->app->basePath();

        $health = [
            'status'      => 'ok',
            'cms_version' => cms_version(),
            'php_version' => PHP_VERSION,
            'server'      => PHP_OS_FAMILY,
            'database'    => $this->checkDatabase(),
            'cache'       => [
                'page_cache_enabled' => setting('page_cache_enabled', '0') === '1',
                'cached_files'       => is_dir($basePath . '/storage/cache') ? count(glob($basePath . '/storage/cache/*.cache')) : 0,
            ],
            'storage'     => $this->checkStorageHealth($basePath),
            'timestamp'   => date('c'),
        ];

        $this->renderAdmin('system/health', [
            'pageTitle' => 'Health-Check',
            'health'    => $health,
            'auth'      => $this->auth(),
            'csrf'      => $this->csrf(),
        ]);
    }

    /**
     * Check storage directories and log file.
     */
    private function checkStorageHealth(string $basePath): array
    {
        $result = [];
        foreach (['cache', 'logs', 'sessions', 'temp'] as $dir) {
            $path = $basePath . '/storage/' . $dir;
            $result[$dir] = [
                'exists'   => is_dir($path),
                'writable' => is_writable($path),
            ];
        }
        $logFile = $basePath . '/storage/logs/error.log';
        if (file_exists($logFile)) {
            $size = filesize($logFile);
            if ($size < 1024) $result['error_log_size'] = $size . ' B';
            elseif ($size < 1048576) $result['error_log_size'] = round($size / 1024, 1) . ' KB';
            else $result['error_log_size'] = round($size / 1048576, 1) . ' MB';
        } else {
            $result['error_log_size'] = '0 B';
        }
        return $result;
    }

    // ─────────────────────────────────────────────────────────
    // Private helpers
    // ─────────────────────────────────────────────────────────

    /**
     * Check required and optional PHP extensions.
     */
    private function checkExtensions(): array
    {
        $required = [
            'pdo'       => 'PDO (database access)',
            'pdo_mysql' => 'PDO MySQL driver',
            'json'      => 'JSON (settings, homepage sections)',
            'mbstring'  => 'Multibyte strings',
            'fileinfo'  => 'File info (upload MIME detection)',
        ];

        $optional = [
            'gd'        => 'GD (image processing)',
            'imagick'   => 'Imagick (ImageMagick image processing)',
            'intl'      => 'Intl (internationalization)',
            'zip'       => 'ZIP',
            'curl'      => 'cURL',
        ];

        $result = [];

        foreach ($required as $ext => $label) {
            $result[] = [
                'name'     => $ext,
                'label'    => $label,
                'loaded'   => extension_loaded($ext),
                'required' => true,
            ];
        }

        foreach ($optional as $ext => $label) {
            $result[] = [
                'name'     => $ext,
                'label'    => $label,
                'loaded'   => extension_loaded($ext),
                'required' => false,
            ];
        }

        return $result;
    }

    /**
     * Check whether key directories exist and are writable.
     */
    private function checkWritableDirs(string $basePath): array
    {
        $dirs = [
            'storage/'           => $basePath . '/storage',
            'storage/logs/'      => $basePath . '/storage/logs',
            'storage/cache/'     => $basePath . '/storage/cache',
            'storage/sessions/'  => $basePath . '/storage/sessions',
            'public/uploads/'    => $basePath . '/public/uploads',
            'public/uploads/blog/'    => $basePath . '/public/uploads/blog',
            'public/uploads/gallery/' => $basePath . '/public/uploads/gallery',
        ];

        $result = [];
        foreach ($dirs as $label => $path) {
            $result[] = [
                'label'    => $label,
                'path'     => $path,
                'exists'   => is_dir($path),
                'writable' => is_dir($path) && is_writable($path),
            ];
        }

        return $result;
    }

    /**
     * Error-Log Viewer – shows last N entries, allows clearing.
     */
    public function errorLog(Request $request, array $params = []): void
    {
        $logFile = $this->app->basePath() . '/storage/logs/error.log';
        $entries = [];
        $logSize = 0;

        if (file_exists($logFile)) {
            $logSize = filesize($logFile);
            $lines   = file($logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            if ($lines) {
                $entries = array_slice($lines, -100);
                $entries = array_reverse($entries);
            }
        }

        // Check for archived logs
        $archiveDir  = $this->app->basePath() . '/storage/logs';
        $archives    = glob($archiveDir . '/error-*.log');
        $archiveInfo = [];
        if ($archives) {
            rsort($archives);
            foreach ($archives as $f) {
                $archiveInfo[] = [
                    'name' => basename($f),
                    'size' => filesize($f),
                    'date' => date('Y-m-d H:i', filemtime($f)),
                ];
            }
        }

        $this->renderAdmin('system/error_log', [
            'pageTitle'   => __('admin.system.error_log_title'),
            'entries'     => $entries,
            'logSize'     => $logSize,
            'archives'    => $archiveInfo,
            'auth'        => $this->auth(),
            'csrf'        => $this->csrf(),
        ]);
    }

    /**
     * Clear the error log file.
     */
    public function clearErrorLog(Request $request, array $params = []): void
    {
        $this->validateCsrf();

        $logFile = $this->app->basePath() . '/storage/logs/error.log';
        if (file_exists($logFile)) {
            file_put_contents($logFile, '');
        }

        $this->session()->setFlash('success', __('admin.system.error_log_cleared'));
        Response::redirect(admin_url('system/error-log'));
    }

    /**
     * Check the database connection and report table count.
     */
    private function checkDatabase(): array
    {
        if (!$this->app->hasService('database')) {
            return [
                'ok'          => false,
                'message'     => 'Database service not initialised.',
                'table_count' => 0,
            ];
        }

        try {
            $db     = $this->app->db();
            $tables = $db->fetchAll(
                "SELECT TABLE_NAME
                 FROM information_schema.TABLES
                 WHERE TABLE_SCHEMA = DATABASE()
                   AND TABLE_NAME LIKE 'iw_%'"
            );

            return [
                'ok'          => true,
                'message'     => 'Connected',
                'table_count' => count($tables),
            ];
        } catch (\Exception $e) {
            return [
                'ok'          => false,
                'message'     => 'Connection error: ' . $e->getMessage(),
                'table_count' => 0,
            ];
        }
    }
}
