<?php

declare(strict_types=1);

namespace Numinix\SeekmodoWordPress\LocalIndex;

/**
 * Parses search queries into term groups (AND/OR/phrases).
 */
final class QueryParser
{
    /**
     * @return array{operator: string, terms: list<string>, phrases: list<string>}
     */
    public static function parse(string $q): array
    {
        $q = trim(preg_replace('/\s+/u', ' ', $q) ?? '');
        $phrases = [];
        if (preg_match_all('/"([^"]+)"/u', $q, $matches)) {
            foreach ($matches[1] as $phrase) {
                $phrases[] = mb_strtolower(trim((string) $phrase));
            }
            $q = preg_replace('/"[^"]+"/u', ' ', $q) ?? '';
        }

        $operator = IndexSettings::defaultOperator();
        $terms = Tokenizer::tokenize(trim($q));

        return [
            'operator' => $operator,
            'terms'    => $terms,
            'phrases'  => array_values(array_filter($phrases)),
        ];
    }

    /**
     * Expand synonyms from local DB + gateway bundle handled elsewhere.
     *
     * @param list<string> $terms
     * @return list<string>
     */
    public static function expandSynonyms(array $terms): array
    {
        global $wpdb;
        $tables = Schema::tableNames();
        $expanded = $terms;
        foreach ($terms as $term) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
            $rows = $wpdb->get_col($wpdb->prepare(
                "SELECT synonym FROM {$tables['synonyms']} WHERE term = %s",
                $term
            ));
            if (is_array($rows)) {
                foreach ($rows as $syn) {
                    $s = mb_strtolower(trim((string) $syn));
                    if ($s !== '' && !in_array($s, $expanded, true)) {
                        $expanded[] = $s;
                    }
                }
            }
        }

        return $expanded;
    }
}
