<?php

namespace App\Modules\Navigation\Services;

use App\Models\User;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;

/**
 * Permission-aware ERP page/module search (EN + AR labels).
 */
final class NavigationSearchService
{
    public function __construct(
        private readonly NavigationService $navigation,
    ) {}

    /**
     * @return list<array{group: string, label: string, url: string, section: string|null}>
     */
    public function search(?User $user, string $query, int $limit = 25, ?string $groupKey = null): array
    {
        $query = trim($query);
        if ($user === null || mb_strlen($query) < 1) {
            return [];
        }

        $needle = Str::lower($query);
        $results = [];

        foreach ($this->navigation->filteredGroups($user) as $group) {
            $gKey = (string) ($group['key'] ?? '');
            if ($groupKey !== null && $groupKey !== '' && $gKey !== $groupKey) {
                continue;
            }

            $groupLabel = (string) ($group['label'] ?? '');

            foreach ($group['items'] ?? [] as $item) {
                $url = $this->resolveUrl($item);
                if ($url === null) {
                    continue;
                }

                $label = (string) ($item['label'] ?? '');
                $labelKey = $item['label_key'] ?? null;
                $haystack = $this->haystack($label, is_string($labelKey) ? $labelKey : null, $groupLabel, $item['section'] ?? null);

                if (! Str::contains($haystack, $needle)) {
                    continue;
                }

                $results[] = [
                    'group' => $groupLabel,
                    'label' => $label,
                    'url' => $url,
                    'section' => isset($item['section']) ? (string) $item['section'] : null,
                ];

                if (count($results) >= $limit) {
                    return $results;
                }
            }
        }

        return $results;
    }

    /**
     * @param  array<string, mixed>  $item
     */
    private function resolveUrl(array $item): ?string
    {
        if (! empty($item['route']) && Route::has((string) $item['route'])) {
            /** @var array<string, mixed> $params */
            $params = is_array($item['route_params'] ?? null) ? $item['route_params'] : [];

            return route((string) $item['route'], $params);
        }

        $href = $item['href'] ?? null;

        return is_string($href) && $href !== '' ? $href : null;
    }

    private function haystack(string $label, ?string $labelKey, string $groupLabel, mixed $section): string
    {
        $parts = [
            $label,
            $groupLabel,
            is_string($section) ? $section : '',
        ];

        if ($labelKey !== null && $labelKey !== '') {
            $parts[] = (string) trans($labelKey, [], 'en');
            $parts[] = (string) trans($labelKey, [], 'ar');
        }

        return Str::lower(implode(' ', array_filter($parts)));
    }
}
