<?php

declare(strict_types=1);

namespace Builder\Core\Http\Controllers\Resource;

use Builder\Core\Foundation\Enums\ToastType;
use Builder\Core\Foundation\Registry;
use Builder\Core\Foundation\Support\Toast;
use Builder\Core\Http\Controllers\Concerns\HasIndexQuery;
use Builder\Core\Http\Controllers\Concerns\HasResourceResolving;
use Builder\Core\Http\Requests\Resource\BulkResourceRequest;
use Illuminate\Http\RedirectResponse;

final class ResourceBulkController
{
    use HasIndexQuery;
    use HasResourceResolving;

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

    public function __invoke(BulkResourceRequest $request, string $resource): RedirectResponse
    {
        $definition = $this->resolveOrFail($resource);
        $model = $definition->getModel();
        $actionKey = $request->input('action');
        $locale = $request->input('locale') ?: null;

        if ($request->boolean('select_all')) {
            $records = $this->buildIndexQuery($request, $definition)->get();
        } else {
            /** @var list<int|string> $ids */
            $ids = $request->input('ids', []);
            $records = $model::whereIn('id', $ids)->get();
        }

        $indexParams = array_filter(['resource' => $resource, 'locale' => $locale]);

        if ($actionKey === 'delete') {
            $this->authorizeResource($request, $definition, 'destroy');
            $records->each(fn (mixed $record) => $record->delete());

            return redirect()->route('builder.resource.index', $indexParams)
                ->with(Toast::flash(ToastType::Success, __('builder::builder.resources.deleted')));
        }

        if ($actionKey === 'bulk_update') {
            $this->authorizeResource($request, $definition, 'edit');

            /** @var array<string, mixed> $data */
            $data = array_filter(
                (array) $request->input('data', []),
                fn (mixed $v): bool => $v !== null && $v !== '',
            );

            $records->each(fn (mixed $record) => $record->update($data));

            return redirect()->route('builder.resource.index', $indexParams)
                ->with(Toast::flash(ToastType::Success, __('builder::builder.resources.updated')));
        }

        $bulkAction = null;
        foreach ($definition->getBulkActions() as $action) {
            if ($action->getKey() === $actionKey) {
                $bulkAction = $action;
                break;
            }
        }

        if ($bulkAction !== null) {
            $handle = $bulkAction->getHandle();
            if ($handle) {
                $handle($records);
            }
        }

        return redirect()->route('builder.resource.index', $indexParams);
    }
}
