<?php

namespace App\Modules\Inventory\Repositories;

use App\Modules\Inventory\Models\ItemCategory;
use App\Support\Lists\ListQuery;
use App\Support\SelectOptionFormatter;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;

class ItemCategoryRepository
{
    /**
     * @return LengthAwarePaginator<int, ItemCategory>
     */
    public function paginatedWithParent(int $perPage = 40): LengthAwarePaginator
    {
        return ItemCategory::query()
            ->with('parent')
            ->orderBy('code')
            ->paginate($perPage);
    }

    public function paginateForIndex(Request $request): LengthAwarePaginator
    {
        $query = ItemCategory::query()->with('parent');

        ListQuery::applySearch($query, $request->input('q'), ['name', 'code']);
        ListQuery::applyBoolean($query, 'is_active', $request->input('is_active'));
        ListQuery::applySort(
            $query,
            $request->input('sort'),
            $request->input('dir'),
            [
                'code' => 'code',
                'name' => 'name',
                'is_active' => 'is_active',
            ],
            'code',
        );

        return ListQuery::paginate($query, $request);
    }

    /**
     * @return array<int, string>
     */
    public function parentSelectOptions(): array
    {
        return ItemCategory::query()
            ->orderBy('code')
            ->get(['id', 'code', 'name'])
            ->mapWithKeys(fn (ItemCategory $c) => [$c->id => $c->code.' — '.$c->name])
            ->all();
    }

    /**
     * @return list<array{value: string, label: string}>
     */
    public function searchForLookup(
        int $tenantId,
        string $query,
        int $limit = 30,
        ?int $excludeId = null,
        ?int $onlyId = null,
    ): array {
        $builder = ItemCategory::query()
            ->where('tenant_id', $tenantId)
            ->orderBy('code');

        if ($onlyId !== null) {
            $builder->whereKey($onlyId);
        } else {
            if ($excludeId !== null) {
                $builder->whereKeyNot($excludeId);
            }
            if ($query !== '') {
                $builder->where(function ($q) use ($query): void {
                    $q->where('name', 'like', '%'.$query.'%')
                        ->orWhere('code', 'like', '%'.$query.'%');
                });
            }
            $builder->limit($limit);
        }

        return SelectOptionFormatter::mapRows(
            $builder->get(['id', 'name', 'code']),
            'name',
            'code',
        );
    }

    /**
     * @param  array<string, mixed>  $attributes
     */
    public function create(int $tenantId, array $attributes): ItemCategory
    {
        return ItemCategory::query()->create(array_merge(['tenant_id' => $tenantId], $attributes));
    }
}
