<?php

namespace App\Http\Controllers;

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

/**
 * ITSWEBER CMS – Health-Check Endpoint
 *
 * Returns JSON with system status. Accessible only to logged-in admins
 * or with a valid API key from settings.
 */
class HealthController extends Controller
{
    public function index(Request $request, array $params = []): void
    {
        header('Content-Type: application/json; charset=utf-8');
        header('Cache-Control: no-store');

        // Auth check: must be logged-in admin or provide valid api_key
        if (!$this->isAuthorized($request)) {
            http_response_code(403);
            echo json_encode(['error' => 'Unauthorized'], JSON_UNESCAPED_UNICODE);
            return;
        }

        $data = [
            'status'      => 'ok',
            'cms_version' => cms_version(),
            'php_version' => PHP_VERSION,
            'server'      => PHP_OS_FAMILY,
            'database'    => $this->checkDatabase(),
            'cache'       => $this->checkCache(),
            'storage'     => $this->checkStorage(),
            'timestamp'   => date('c'),
        ];

        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    }

    private function isAuthorized(Request $request): bool
    {
        // Check session-based admin auth
        if ($this->app->hasService('auth')) {
            $auth = $this->auth();
            if ($auth->check() && $auth->isAdmin()) {
                return true;
            }
        }

        // Check API key from query parameter
        $apiKey = $request->input('api_key', '');
        if ($apiKey !== '') {
            $configuredKey = setting('health_api_key', '');
            return $configuredKey !== '' && hash_equals($configuredKey, $apiKey);
        }

        return false;
    }

    private function checkDatabase(): array
    {
        try {
            $db = $this->app->db();
            $row = $db->fetchOne("SELECT COUNT(*) AS cnt FROM iw_migrations");
            return [
                'status'     => 'ok',
                'migrations' => (int) ($row['cnt'] ?? 0),
            ];
        } catch (\Throwable $e) {
            return [
                'status' => 'error',
                'error'  => $e->getMessage(),
            ];
        }
    }

    private function checkCache(): array
    {
        $cacheDir = $this->app->basePath() . '/storage/cache';
        $enabled  = setting('page_cache_enabled', '0') === '1';
        $files    = is_dir($cacheDir) ? count(glob($cacheDir . '/*.cache')) : 0;

        return [
            'page_cache_enabled' => $enabled,
            'cached_files'       => $files,
        ];
    }

    private function checkStorage(): array
    {
        $base   = $this->app->basePath() . '/storage';
        $result = [];

        foreach (['cache', 'logs', 'sessions', 'temp'] as $dir) {
            $path = $base . '/' . $dir;
            $result[$dir] = [
                'exists'   => is_dir($path),
                'writable' => is_writable($path),
            ];
        }

        // Log file size
        $logFile = $base . '/logs/error.log';
        if (file_exists($logFile)) {
            $result['error_log_size'] = $this->formatBytes(filesize($logFile));
        }

        return $result;
    }

    private function formatBytes(int $bytes): string
    {
        if ($bytes < 1024) return $bytes . ' B';
        if ($bytes < 1048576) return round($bytes / 1024, 1) . ' KB';
        return round($bytes / 1048576, 1) . ' MB';
    }
}
