<?php

namespace App\Modules\Platform\Geography\Repositories;

use App\Modules\Platform\Geography\Models\GeoCountry;
use App\Support\LocalizedName;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class GeoCountryRepository
{
    /**
     * @return list<array{value: string, label: string}>
     */
    public function searchForLookup(string $query, int $limit = 30, ?int $onlyId = null): array
    {
        $builder = GeoCountry::query()
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->orderBy('id');

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

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

    /**
     * @return array<int, string>
     */
    public function listForSelect(): array
    {
        return $this->mapToPluck(
            GeoCountry::query()
                ->where('is_active', true)
                ->orderBy('sort_order')
                ->orderBy('id')
                ->get(['id', 'name', 'code']),
        );
    }

    public function paginateForAdmin(int $perPage = 25): LengthAwarePaginator
    {
        return GeoCountry::query()
            ->withCount('regions')
            ->orderBy('sort_order')
            ->orderBy('id')
            ->paginate($perPage)
            ->withQueryString();
    }

    /**
     * @param  Collection<int, GeoCountry>  $rows
     * @return array<int, string>
     */
    private function mapToPluck(Collection $rows): array
    {
        $options = [];
        foreach ($rows as $row) {
            $options[(int) $row->id] = LocalizedName::fromModel($row);
        }

        return $options;
    }

    /**
     * @param  Collection<int, GeoCountry>  $rows
     * @return list<array{value: string, label: string}>
     */
    private function mapRows(Collection $rows): array
    {
        $options = [];
        foreach ($rows as $row) {
            $options[] = [
                'value' => (string) $row->id,
                'label' => LocalizedName::fromModel($row),
            ];
        }

        return $options;
    }
}
