<?php

declare(strict_types=1);

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;

/**
 * System health endpoints.
 * Public: /api/v1/public/health — minimal bilgi, no auth.
 * Auth'd: /api/v1/health — detaylı DB/cache/queue durumu.
 */
class HealthApiController extends Controller
{
    /**
     * Authenticated health check — detaylı durum.
     */
    public function index(Request $request): JsonResponse
    {
        $checks = $this->runChecks(detailed: true);
        $status = $this->overallStatus($checks);

        return response()->json([
            'data' => [
                'status' => $status,
                'version' => config('app.version', '1.0.0'),
                'env' => app()->environment(),
                'checks' => $checks,
                'checked_at' => now()->toIso8601String(),
            ],
        ], $status === 'ok' ? 200 : 503);
    }

    /**
     * Public health check — minimal (503 veya 200).
     */
    public function public(): JsonResponse
    {
        $checks = $this->runChecks(detailed: false);
        $status = $this->overallStatus($checks);

        return response()->json([
            'status' => $status,
            'checked_at' => now()->toIso8601String(),
        ], $status === 'ok' ? 200 : 503);
    }

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

    /**
     * @return array<string, array{status: string, latency_ms?: int|null, error?: string}>
     */
    private function runChecks(bool $detailed): array
    {
        $checks = [];

        // Database
        try {
            $start = microtime(true);
            DB::selectOne('SELECT 1');
            $checks['database'] = [
                'status' => 'ok',
                'latency_ms' => $detailed ? (int) ((microtime(true) - $start) * 1000) : null,
            ];
        } catch (\Throwable $e) {
            $checks['database'] = ['status' => 'fail', 'error' => $detailed ? $e->getMessage() : 'unavailable'];
        }

        if ($detailed) {
            // Cache
            try {
                $key = 'healthcheck_'.time();
                Cache::put($key, 1, 5);
                Cache::forget($key);
                $checks['cache'] = ['status' => 'ok'];
            } catch (\Throwable $e) {
                $checks['cache'] = ['status' => 'fail', 'error' => $e->getMessage()];
            }

            // Queue (basit: horizon çalışıyor mu)
            $horizonActive = Cache::get('horizon:master:status') !== null;
            $checks['queue'] = ['status' => $horizonActive ? 'ok' : 'degraded'];
        }

        return $checks;
    }

    private function overallStatus(array $checks): string
    {
        foreach ($checks as $check) {
            if (($check['status'] ?? 'ok') === 'fail') {
                return 'fail';
            }
        }
        foreach ($checks as $check) {
            if (($check['status'] ?? 'ok') === 'degraded') {
                return 'degraded';
            }
        }

        return 'ok';
    }
}
