<?php

declare(strict_types=1);

namespace App\Http\Controllers\Admin;

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

/**
 * Admin: API Tester (Phase 5 — Dev Experience)
 *
 * Embedded Swagger-like API explorer that executes requests
 * against the panel's own API and logs the results.
 */
class ApiTesterController extends Controller
{
    public function index(): Response
    {
        // Load OpenAPI spec for endpoint browser
        $openapiPath = public_path('docs/openapi.json');
        $openapi = file_exists($openapiPath)
            ? json_decode(file_get_contents($openapiPath), true)
            : null;

        $endpoints = [];
        if ($openapi) {
            foreach ($openapi['paths'] ?? [] as $path => $methods) {
                foreach ($methods as $method => $spec) {
                    if (in_array($method, ['get', 'post', 'put', 'patch', 'delete'])) {
                        $endpoints[] = [
                            'method' => strtoupper($method),
                            'path' => $path,
                            'summary' => $spec['summary'] ?? '',
                            'tags' => $spec['tags'] ?? [],
                        ];
                    }
                }
            }
        }

        // Recent test requests for re-run history
        $recent = DB::table('api_test_requests')
            ->where('user_id', auth()->id())
            ->orderByDesc('sent_at')
            ->limit(20)
            ->get();

        return Inertia::render('Admin/ApiTester/Index', compact('endpoints', 'recent'));
    }

    public function execute(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'method' => ['required', 'in:GET,POST,PUT,PATCH,DELETE'],
            'path' => ['required', 'string', 'max:500', 'starts_with:/'],
            'params' => ['nullable', 'array'],
            'headers' => ['nullable', 'array'],
            'headers.*' => ['nullable', 'string', 'max:500'],
            'body' => ['nullable', 'string', 'max:65536'],
            'use_token' => ['nullable', 'string', 'max:500'],
        ]);

        $baseUrl = config('app.url');
        $url = rtrim($baseUrl, '/').$validated['path'];

        $headers = $validated['headers'] ?? [];
        if (! empty($validated['use_token'])) {
            $headers['Authorization'] = 'Bearer '.$validated['use_token'];
        }

        $start = microtime(true);
        try {
            $httpRequest = Http::timeout(30)->withHeaders($headers);

            if (! empty($validated['body'])) {
                $httpRequest = $httpRequest->withBody($validated['body'], 'application/json');
            }

            $method = strtolower($validated['method']);
            $response = $httpRequest->{$method}($url, $validated['params'] ?? []);

            $duration = (int) ((microtime(true) - $start) * 1000);

            $result = [
                'status_code' => $response->status(),
                'response_body' => $response->body(),
                'response_headers' => $response->headers(),
                'duration_ms' => $duration,
            ];
        } catch (\Throwable $e) {
            $duration = (int) ((microtime(true) - $start) * 1000);
            $result = [
                'status_code' => null,
                'duration_ms' => $duration,
                'error' => $e->getMessage(),
            ];
        }

        // Log request + response
        DB::table('api_test_requests')->insert([
            'user_id' => auth()->id(),
            'method' => $validated['method'],
            'path' => $validated['path'],
            'params' => json_encode($validated['params'] ?? []),
            'headers' => json_encode($headers),
            'body' => $validated['body'] ?? null,
            'status_code' => $result['status_code'] ?? null,
            'response_body' => substr($result['response_body'] ?? '', 0, 50000),
            'duration_ms' => $result['duration_ms'] ?? 0,
            'sent_at' => now(),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return response()->json($result);
    }
}
