<?php

namespace App\Services;

use App\Models\ServiceAgendaItem;

class AgendaMatcherService
{
    /**
     * Check if an item title matches a glob-style pattern.
     * Supports * wildcard (matches any characters).
     * Case-insensitive.
     */
    public function matches(string $itemTitle, string $pattern): bool
    {
        $normalizedTitle = strtolower(trim($itemTitle));
        $normalizedPattern = strtolower(trim($pattern));

        return fnmatch($normalizedPattern, $normalizedTitle, FNM_CASEFOLD);
    }

    /**
     * Check if an item title matches any of the patterns.
     *
     * @param  array  $patterns  Array of glob-style patterns
     */
    public function matchesAny(string $itemTitle, array $patterns): bool
    {
        foreach ($patterns as $pattern) {
            if ($this->matches($itemTitle, $pattern)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Find the first ServiceAgendaItem whose title matches any of the patterns.
     *
     * @param  array  $agendaItems  Array of ServiceAgendaItem
     * @param  string  $patterns  Comma-separated patterns (e.g. "Information*,Hinweis*")
     */
    public function findFirstMatch(array $agendaItems, string $patterns): ?ServiceAgendaItem
    {
        $patternList = array_map(fn ($p) => trim($p), explode(',', $patterns));
        $patternList = array_filter($patternList, fn ($p) => $p !== '');

        foreach ($agendaItems as $item) {
            if ($this->matchesAny($item->title, $patternList)) {
                return $item;
            }
        }

        return null;
    }

    /**
     * Filter array of ServiceAgendaItems to only those between start and end boundary items.
     * Boundary items are identified by matching start/end patterns (comma-separated strings).
     * The boundary items themselves are EXCLUDED from the result.
     *
     * If startPattern is empty/null: start from the first item
     * If endPattern is empty/null: go to the last item
     *
     * @param  array  $items  Array of ServiceAgendaItem
     * @param  string|null  $startPattern  Comma-separated start patterns or null
     * @param  string|null  $endPattern  Comma-separated end patterns or null
     * @return array Filtered items (boundaries excluded)
     */
    public function filterBetween(array $items, ?string $startPattern, ?string $endPattern): array
    {
        if (empty($items)) {
            return [];
        }

        $startIdx = 0;
        $endIdx = count($items) - 1;

        // Find start boundary index
        if ($startPattern !== null && $startPattern !== '') {
            $startItem = $this->findFirstMatch($items, $startPattern);
            if ($startItem === null) {
                // No matching start pattern — return empty
                return [];
            }
            // Find the index of the start item
            foreach ($items as $index => $item) {
                if ($item->id === $startItem->id) {
                    $startIdx = $index + 1; // Exclude the boundary item
                    break;
                }
            }
        }

        // Find end boundary index
        if ($endPattern !== null && $endPattern !== '') {
            $endItem = $this->findFirstMatch($items, $endPattern);
            if ($endItem === null) {
                // No matching end pattern — return empty
                return [];
            }
            // Find the index of the end item (search from end for clarity)
            foreach (array_reverse($items, true) as $index => $item) {
                if ($item->id === $endItem->id) {
                    $endIdx = $index - 1; // Exclude the boundary item
                    break;
                }
            }
        }

        // Return slice
        if ($startIdx > $endIdx) {
            return [];
        }

        return array_slice($items, $startIdx, $endIdx - $startIdx + 1);
    }
}
