<?php

namespace App\Http\Controllers;

use App\Services\ComponentRendererService;
use App\Services\ComponentScannerService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ComponentRegistryApiController extends Controller
{
    public function __construct(private readonly ComponentScannerService $scannerService, private readonly ComponentRendererService $rendererService)
    {
    }

    /**
     * Override callAction to skip parent's admin auth requirements.
     */
    #[\Override]
    public function callAction($method, $parameters)
    {
        return $this->{$method}(...array_values($parameters));
    }

    /**
     * GET /api/components
     * Return list of all discoverable components with metadata
     */
    public function index(Request $request): JsonResponse
    {
        try {
            $categoryFilter = $request->query('category');
            $searchQuery = $request->query('search');
            $limit = min((int) $request->query('limit', 50), 200);
            $page = max((int) $request->query('page', 1), 1);

            // Get all components
            $discovery = $this->scannerService->discoverComponents();
            $allComponents = $discovery['components'];
            $categories = $discovery['categories'];

            // Apply filters
            $filteredComponents = $allComponents;

            if ($categoryFilter) {
                $filteredComponents = array_filter($filteredComponents, static fn($component) => $component->category === $categoryFilter);
            }

            if ($searchQuery) {
                $filteredComponents = array_filter($filteredComponents, static function ($component) use ($searchQuery) {
                    $query = strtolower($searchQuery);

                    return (
                        str_contains(strtolower((string) $component->name), $query)
                        || str_contains(strtolower((string) $component->description), $query)
                    );
                });
            }

            // Convert to indexed array for pagination
            $filteredComponents = array_values($filteredComponents);
            $total = count($filteredComponents);

            // Apply pagination
            $offset = ($page - 1) * $limit;
            $paginatedComponents = array_slice($filteredComponents, $offset, $limit);

            // Convert to array format
            $componentsData = array_map(static fn($component) => $component->toArray(), $paginatedComponents);

            return response()->json([
                'data' => $componentsData,
                'meta' => [
                    'total' => $total,
                    'per_page' => $limit,
                    'current_page' => $page,
                    'last_page' => ceil($total / $limit),
                ],
                'categories' => $categories,
            ]);
        } catch (\Exception $e) {
            \Log::error('Component Registry API Error: '.$e->getMessage());

            return response()->json([
                'error' => 'Failed to scan component directory',
                'details' => config('app.debug') ? $e->getMessage() : 'Internal server error',
            ], 500);
        }
    }

    /**
     * GET /api/components/{path}
     * Return detailed information about a specific component
     */
    public function show(Request $request, string $path): JsonResponse
    {
        try {
            $component = $this->scannerService->findComponent($path);

            if (! $component) {
                return response()->json([
                    'error' => 'Component not found',
                    'path' => $path,
                ], 404);
            }

            // Get component with sample data and usage instructions
            $componentData = $this->rendererService->getComponentWithSampleData($component);

            return response()->json($componentData);
        } catch (\Exception $e) {
            \Log::error("Component Detail API Error for {$path}: ".$e->getMessage());

            return response()->json([
                'error' => 'Failed to load component details',
                'details' => config('app.debug') ? $e->getMessage() : 'Internal server error',
                'path' => $path,
            ], 500);
        }
    }
}
