<?php

declare(strict_types=1);

namespace Builder\Core\Http\Controllers\Resource;

use Builder\Core\Foundation\Contracts\BuilderAccessible;
use Builder\Core\Foundation\Contracts\Translatable;
use Builder\Core\Foundation\Middleware\BuilderAuth;
use Builder\Core\Foundation\Registry;
use Builder\Core\Foundation\Resources\ResourcePersistenceService;
use Builder\Core\Http\Controllers\Concerns\HasResourceResolving;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

final class ResourceQuickStoreController
{
    use HasResourceResolving;

    public function __construct(
        private readonly Registry $registry,
        private readonly ResourcePersistenceService $persistenceService,
    ) {}

    public function __invoke(Request $request, string $resource): JsonResponse
    {
        $definition = $this->resolveOrFail($resource);
        $this->authorizeResource($request, $definition, 'create');

        $rules = $definition->getRulesForAction('create') ?: $definition->getRules();

        try {
            $data = empty($rules)
                ? $request->except(['_token', '_method', '_locale', '_label_key'])
                : $request->validate($rules);
        } catch (ValidationException $e) {
            return response()->json(['errors' => $e->errors()], 422);
        }

        $guard = BuilderAuth::guard();
        /** @var BuilderAccessible $user */
        $user = $request->user($guard);
        $data = $this->persistenceService->stripRestrictedFields($data, $definition, $user);
        $locale = $request->input('_locale');
        $labelKey = (string) $request->input('_label_key', 'name');

        $record = $this->persistenceService->store($definition, $data, $locale, $user);

        $label = null;

        if ($locale && $record instanceof Translatable) {
            $translation = $record->getTranslation($locale);
            $label = $translation === null ? null : $translation->{$labelKey};
        }

        $label ??= $record->{$labelKey} ?? (string) $record->getKey();

        return response()->json([
            'id' => $record->getKey(),
            'label' => (string) $label,
        ]);
    }
}
