"""
QUERY PARSER
════════════

Parse user query để extract keywords và build SQL WHERE clause

Functions:
- parse_query(): Extract filters từ query text
- build_where_clause(): Convert filters thành SQL WHERE
"""

import re
import logging
from .keyword_mappings import KEYWORD_MAPPINGS

logger = logging.getLogger(__name__)


def is_word_match(keyword: str, query: str) -> bool:
    """
    Check keyword có phải là từ riêng biệt trong query không
    Tránh case "việt nam" match "nam"
    
    VD:
    - "nam" trong "áo nam" → True (từ riêng biệt)
    - "nam" trong "việt nam" → False (substring của từ khác)
    - "bé gái" trong "áo bé gái" → True
    """
    # Pattern: keyword phải có word boundary (space, start, end) ở 2 đầu
    # Dùng \b cho word boundary với tiếng Việt cần xử lý đặc biệt
    
    # Escape special regex characters trong keyword
    escaped_keyword = re.escape(keyword)
    
    # Pattern: từ phải đứng riêng (có space hoặc đầu/cuối string)
    pattern = r'(?:^|[\s,\.!?])' + escaped_keyword + r'(?:[\s,\.!?]|$)'
    
    return bool(re.search(pattern, query))


def parse_query(query: str) -> dict:
    """
    Parse query text và extract filters dựa trên KEYWORD_MAPPINGS
    
    Args:
        query: User query string (VD: "áo mùa đông cho bé gái màu hồng")
    
    Returns:
        dict: Filters grouped by field
        {
            "season": {"values": ["Fall Winter"], "op": "IN"},
            "gender_by_product": {"values": ["female"], "op": "="},
            ...
        }
    
    Note:
    - Nếu không có keyword nào match → trả về {} → không filter gì cả (lấy hết)
    - Keywords phải là từ riêng biệt (word boundary), tránh "việt nam" → "nam"
    """
    query_lower = query.lower().strip()
    filters = {}
    matched_keywords = set()
    
    # Sort keywords by length (dài trước) để match chính xác hơn
    # VD: "áo khoác" phải match trước "áo"
    # VD: "bé gái" phải match trước "bé"
    sorted_keywords = sorted(KEYWORD_MAPPINGS.keys(), key=len, reverse=True)
    
    for keyword in sorted_keywords:
        # Check keyword có xuất hiện như từ riêng biệt không
        if not is_word_match(keyword, query_lower):
            continue
            
        # Kiểm tra keyword này có phải là substring của keyword đã match không
        # VD: đã match "bé gái" thì không match "bé" nữa
        is_substring_of_matched = False
        for matched in matched_keywords:
            if keyword in matched and keyword != matched:
                is_substring_of_matched = True
                break
        
        if is_substring_of_matched:
            continue
        
        mapping = KEYWORD_MAPPINGS[keyword]
        field = mapping["field"]
        
        # Chỉ lấy field đầu tiên match (không override)
        if field not in filters:
            filters[field] = {
                "values": mapping["values"],
                "op": mapping["op"]
            }
            matched_keywords.add(keyword)
            logger.debug(f"Matched keyword: '{keyword}' → {field} = {mapping['values']}")
    
    logger.info(f"Query '{query}' → Extracted filters: {filters}")
    return filters


def build_where_clause(filters: dict) -> str:
    """
    Build SQL WHERE clause từ extracted filters
    
    Args:
        filters: Dict of filters from parse_query()
    
    Returns:
        str: SQL WHERE clause (VD: "WHERE season IN ('Fall Winter') AND ...")
             Returns empty string if no filters
    """
    if not filters:
        return ""
    
    clauses = []
    
    for field, config in filters.items():
        values = config["values"]
        op = config["op"]
        
        if op == "=":
            # Single value equality
            # VD: gender_by_product = 'female'
            clauses.append(f"{field} = '{values[0]}'")
            
        elif op == "IN":
            # Multiple values
            # VD: season IN ('Fall Winter')
            vals_str = ", ".join([f"'{v}'" for v in values])
            clauses.append(f"{field} IN ({vals_str})")
            
        elif op == "LIKE":
            # Text search với LIKE
            # VD: (product_line_vn LIKE '%Áo%' OR product_line_vn LIKE '%Áo khoác%')
            like_parts = [f"{field} LIKE '%{v}%'" for v in values]
            if len(like_parts) == 1:
                clauses.append(like_parts[0])
            else:
                clauses.append(f"({' OR '.join(like_parts)})")
    
    where_clause = "WHERE " + " AND ".join(clauses)
    logger.debug(f"Built WHERE clause: {where_clause}")
    
    return where_clause


def get_matched_keywords(query: str) -> list[str]:
    """
    Get list of keywords that were matched in the query
    Useful for debugging/logging
    """
    query_lower = query.lower().strip()
    matched = []
    sorted_keywords = sorted(KEYWORD_MAPPINGS.keys(), key=len, reverse=True)
    
    for keyword in sorted_keywords:
        # Check word boundary
        if not is_word_match(keyword, query_lower):
            continue
        # Check not substring of already matched
        is_sub = any(keyword in m and keyword != m for m in matched)
        if not is_sub:
            matched.append(keyword)
    
    return matched
