<?php

namespace App\Services\Administracion\Crud\Concerns;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

trait BuildsCrudEntityData
{
    /**
     * @return array<string, mixed>|RedirectResponse
     */
    public function buildIndexData(Request $request): array|RedirectResponse
    {
        $model = $this->newModel();
        $perPage = $this->resolvePerPage($request);
        $columns = $this->getColumns($model);
        $editableColumns = $this->resolveEditableColumns($model);
        $fieldOptions = $this->fieldOptions();
        $tableLabels = $this->tableLabels;
        $defaultValues = $this->resolveDefaultValues($editableColumns);

        $displayColumns = $this->tableColumns !== [] ? $this->tableColumns : $columns;
        $auditAuthorColumn = $this->resolveAuditAuthorColumn($model, $displayColumns);
        if ($auditAuthorColumn !== null) {
            $displayColumns[] = $auditAuthorColumn;
            $fieldOptions[$auditAuthorColumn] = $this->buildUsuarioReferenceOptions();
            $tableLabels[$auditAuthorColumn] ??= 'Realizado por';

            $auditDateColumn = $this->resolveAuditDateColumn($model, $displayColumns);
            if ($auditDateColumn !== null) {
                $displayColumns[] = $auditDateColumn;
                $tableLabels[$auditDateColumn] ??= 'Fecha del cambio';
            }
        }

        $displayColumnLabels = $this->buildColumnLabels($displayColumns, $tableLabels);
        $formColumnLabels = $this->buildColumnLabels($editableColumns, $this->formLabels);
        $searchColumns = $this->searchColumns !== [] ? $this->searchColumns : $displayColumns;
        $searchPlaceholder = $this->searchPlaceholder ?? ('Buscar en ' . $this->entityLabels['plural']);
        $search = trim((string) $request->query('q', ''));

        $searchRedirect = $this->resolveSearchRedirect($search);
        if ($searchRedirect instanceof RedirectResponse) {
            return $searchRedirect;
        }

        $query = $this->newQuery();
        if ($search !== '') {
            $this->applySearch($query, $search, $searchColumns);
        }

        $this->configureIndexQuery($query, $model);

        $rows = $query
            ->paginate($perPage)
            ->withQueryString();

        return array_merge([
            'entity' => $this->entity,
            'modelClass' => $this->modelClass,
            'entitySingularLabel' => $this->entityLabels['singular'],
            'entityPluralLabel' => $this->entityLabels['plural'],
            'entityCreateLabel' => $this->entityLabels['create'],
            'columns' => $displayColumns,
            'columnLabels' => $displayColumnLabels,
            'formColumnLabels' => $formColumnLabels,
            'editableColumns' => $editableColumns,
            'fieldOptions' => $fieldOptions,
            'defaultValues' => $defaultValues,
            'showRowNumber' => $this->showRowNumber,
            'rows' => $rows,
            'primaryKey' => $model->getKeyName(),
            'perPage' => $perPage,
            'search' => $search,
            'searchPlaceholder' => $searchPlaceholder,
            'isReadOnly' => $this->isReadOnly(),
        ], $this->additionalIndexData());
    }

    /**
     * @return array<string, mixed>
     */
    public function buildFormData(?int $id = null): array
    {
        $model = $this->newModel();
        $editableColumns = $this->resolveEditableColumns($model);

        return [
            'entity' => $this->entity,
            'modelClass' => $this->modelClass,
            'entitySingularLabel' => $this->entityLabels['singular'],
            'entityPluralLabel' => $this->entityLabels['plural'],
            'columns' => $editableColumns,
            'columnLabels' => $this->buildColumnLabels($editableColumns, $this->formLabels),
            'fieldOptions' => $this->fieldOptions(),
            'defaultValues' => $this->resolveDefaultValues($editableColumns),
            'primaryKey' => $model->getKeyName(),
            'record' => $id === null ? null : $this->modelClass::query()->findOrFail($id),
            'mode' => $id === null ? 'create' : 'edit',
        ];
    }

    /**
     * @return array<string, mixed>
     */
    public function buildImportFormData(): array
    {
        $model = $this->newModel();
        $editableColumns = $this->resolveEditableColumns($model);

        return [
            'entity' => $this->entity,
            'entitySingularLabel' => $this->entityLabels['singular'],
            'entityPluralLabel' => $this->entityLabels['plural'],
            'columns' => $editableColumns,
            'columnLabels' => $this->buildColumnLabels($editableColumns, $this->formLabels),
            'primaryKey' => $model->getKeyName(),
            'lookupColumns' => $this->resolveImportLookupColumns($model),
        ];
    }
}