<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class SystemController extends Controller
{
    public function health(Request $request): JsonResponse
    {
        return $this->response($request, [
            'ok' => true,
            'time' => now()->toIso8601String(),
            'app' => config('app.name'),
        ]);
    }

    public function metricsLite(Request $request): JsonResponse
    {
        if (! $this->metricsEnabled()) {
            return $this->response($request, [
                'ok' => false,
                'error' => 'metrics_disabled',
            ], 404);
        }

        return $this->response($request, [
            'ok' => true,
            'time' => now()->toIso8601String(),
            'php_version' => PHP_VERSION,
            'memory_used_bytes' => memory_get_usage(true),
            'cache_driver' => (string) config('cache.default'),
        ]);
    }

    public function metrics(Request $request): JsonResponse
    {
        if (! $this->metricsEnabled()) {
            return $this->response($request, [
                'ok' => false,
                'error' => 'metrics_disabled',
            ], 404);
        }

        if (! $this->canAccessMetrics($request)) {
            return $this->response($request, [
                'ok' => false,
                'error' => 'forbidden',
            ], 403);
        }

        $dbOk = true;
        try {
            DB::connection()->getPdo();
        } catch (\Throwable) {
            $dbOk = false;
        }

        return $this->response($request, [
            'ok' => true,
            'time' => now()->toIso8601String(),
            'php_version' => PHP_VERSION,
            'memory_used_bytes' => memory_get_usage(true),
            'db' => $dbOk ? 'ok' : 'down',
            'cache_driver' => (string) config('cache.default'),
            'cache_health' => $this->cacheHealth(),
            'system' => [
                'loadavg' => function_exists('sys_getloadavg') ? array_map(
                    fn (float $n): string => number_format($n, 2, '.', ''),
                    sys_getloadavg() ?: []
                ) : null,
            ],
        ]);
    }

    private function cacheHealth(): string
    {
        try {
            $key = 'dw_metrics_ping';
            Cache::put($key, 'ok', 60);
            $val = Cache::get($key);

            return $val === 'ok' ? 'ok' : 'degraded';
        } catch (\Throwable) {
            return 'down';
        }
    }

    private function metricsEnabled(): bool
    {
        return (bool) config('dewemoji.metrics.enabled', true);
    }

    private function canAccessMetrics(Request $request): bool
    {
        $token = trim((string) config('dewemoji.metrics.token', ''));
        $provided = trim((string) $request->header('X-Metrics-Token', $request->query('token', '')));
        if ($token !== '' && hash_equals($token, $provided)) {
            return true;
        }

        $allowIps = config('dewemoji.metrics.allow_ips', []);
        if (is_array($allowIps) && in_array($request->ip(), $allowIps, true)) {
            return true;
        }

        return false;
    }

    /**
     * @param  array<string,mixed>  $payload
     */
    private function response(Request $request, array $payload, int $status = 200): JsonResponse
    {
        $headers = [
            'X-Dewemoji-Tier' => 'free',
            'X-Dewemoji-Plan' => 'free',
            'Vary' => 'Origin',
            'Access-Control-Allow-Methods' => (string) config('dewemoji.cors.allow_methods', 'GET, POST, OPTIONS'),
            'Access-Control-Allow-Headers' => (string) config('dewemoji.cors.allow_headers', 'Content-Type, Authorization, X-Api-Key, X-Admin-Token, X-Account-Id, X-Dewemoji-Frontend, X-Extension-Token'),
        ];

        $origin = (string) $request->headers->get('Origin', '');
        $allowedOrigins = config('dewemoji.cors.allowed_origins', []);
        if (is_array($allowedOrigins) && in_array($origin, $allowedOrigins, true)) {
            $headers['Access-Control-Allow-Origin'] = $origin;
        }

        return response()->json($payload, $status, $headers);
    }
}
