<?php

declare(strict_types=1);

namespace Builder\Core\Http\Controllers\Resource;

use Builder\Core\Exceptions\CircularHierarchyException;
use Builder\Core\Foundation\Contracts\BuilderAccessible;
use Builder\Core\Foundation\Enums\ToastType;
use Builder\Core\Foundation\Middleware\BuilderAuth;
use Builder\Core\Foundation\Registry;
use Builder\Core\Foundation\Resources\ResourcePersistenceService;
use Builder\Core\Foundation\Support\Toast;
use Builder\Core\Http\Controllers\Concerns\HasResourceResolving;
use Builder\Core\Http\Requests\Resource\UpdateResourceRequest;
use Illuminate\Http\RedirectResponse;

final class ResourceUpdateController
{
    use HasResourceResolving;

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

    public function __invoke(UpdateResourceRequest $request, string $resource, int|string $id): RedirectResponse
    {
        $definition = $this->resolveOrFail($resource);

        /** @var BuilderAccessible $user */
        $user = $request->user(BuilderAuth::guard());

        $data = $this->persistenceService->stripRestrictedFields($request->validated(), $definition, $user);
        $locale = $request->input('_locale');

        $model = $definition->getModel();
        $record = $model::findOrFail($id);

        try {
            $this->persistenceService->update($definition, $record, $data, $locale, $user);
        } catch (CircularHierarchyException $e) {
            return back()->withErrors(['parent_id' => $e->getMessage()])->withInput();
        }

        return redirect()->route('builder.resource.edit', array_filter(['resource' => $resource, 'id' => $id, 'locale' => $locale]))
            ->with(Toast::flash(ToastType::Success, __('builder::builder.resources.updated')));
    }
}
