<?php

namespace App\Traits\Basics;

use Illuminate\Http\Request;

trait Select2Ajax
{
    protected function select2Response($query, Request $request, array $searchColumns, array $textColumns, $additional = null): array
    {
        $page   = $request->input('page', 1);
        $search = $request->input('search');
        $id     = $request->input('id');

        $customer = $request->input('customer');

        // ===== fetch selected item =====
        if ($id) {
            $items = $query->whereIn('id', (array) $id)->get();
            return [
                'items' => $this->formatSelect2($items, $textColumns, $additional)
            ];
        }

        // ===== search =====
        if ($search) {
            $query->where(function ($q) use ($search, $searchColumns) {
                foreach ($searchColumns as $column) {
                    if (str_contains($column, '.')) {
                        [$relation, $relColumn] = explode('.', $column);
                        $q->orWhereHas($relation, function ($qr) use ($relColumn, $search) {
                            $qr->where($relColumn, 'like', "%{$search}%");
                        });
                    } else {
                        $q->orWhere($column, 'like', "%{$search}%");
                    }
                }
            });
        }

        if ($customer) {
            $query->where('customer_id', $customer);
        }

        $items = $query->paginate(LIMIT_SELECT2, ['*'], 'page', $page);

        return [
            'items' => $this->formatSelect2($items->getCollection(), $textColumns, $additional),
            'more'  => $items->hasMorePages()
        ];
    }

    private function formatSelect2($items, array $columns, $additional = null): array
    {
        return $items->map(function ($item) use ($columns, $additional) {

            $values = [];

            foreach ($columns as $column) {
                if (str_contains($column, '.')) {
                    $values[] = data_get($item, $column);
                } else {
                    $values[] = $item->{$column};
                }
            }

            if ($additional) {
                $values[] = $additional;
            }

            return [
                'id'   => $item->id,
                'text' => collect($values)->filter()->implode(' | ')
            ];
        })->toArray();
    }
}
