"""Keyword extraction utility for transaction categorization."""

import re
from typing import Optional

STOP_WORDS = frozenset(
    {
        "the",
        "and",
        "for",
        "are",
        "but",
        "not",
        "you",
        "all",
        "can",
        "had",
        "her",
        "was",
        "one",
        "our",
        "out",
        "day",
        "has",
        "his",
        "how",
        "its",
        "may",
        "new",
        "now",
        "old",
        "see",
        "way",
        "who",
        "did",
        "get",
        "got",
        "let",
        "say",
        "she",
        "too",
        "use",
        "from",
        "have",
        "been",
        "each",
        "make",
        "like",
        "long",
        "look",
        "many",
        "some",
        "them",
        "then",
        "than",
        "this",
        "that",
        "what",
        "with",
        "will",
        "your",
        "into",
        "over",
        "such",
        "take",
        "they",
        "come",
        "made",
        "find",
        "more",
        "also",
        "here",
        "most",
        "very",
        "when",
        "just",
        "only",
        "know",
        "which",
        "about",
        "after",
        "other",
        "their",
        "there",
        "these",
        "those",
        "would",
        "could",
        "should",
        "being",
        "where",
        "every",
        "through",
        "between",
        "payment",
        "transfer",
        "transaction",
        "debit",
        "credit",
        "card",
        "purchase",
        "pos",
        "ref",
        "reference",
        "date",
        "amount",
    }
)


def extract_keywords(text: Optional[str]) -> list[str]:
    """Extract meaningful keywords from transaction text.

    Splits on non-alphanumeric characters, lowercases, removes stop words
    and tokens shorter than 3 characters.
    """
    if not text:
        return []
    tokens = re.findall(r"[a-z0-9]+", text.lower())
    return [t for t in tokens if len(t) >= 3 and t not in STOP_WORDS]
