import logging

# Note: tracing handled by parent data_retrieval_tool via context manager


logger = logging.getLogger(__name__)


def _get_price_clauses(params, sql_params: list) -> list[str]:
    """Lọc theo giá (Parameterized). Bỏ qua giá trị 0 (Gemini gửi 0 thay vì null)."""
    clauses = []
    p_min = getattr(params, "price_min", None)
    if p_min and p_min > 0:
        clauses.append("sale_price >= %s")
        sql_params.append(p_min)
    p_max = getattr(params, "price_max", None)
    if p_max and p_max > 0:
        clauses.append("sale_price <= %s")
        sql_params.append(p_max)

    return clauses


def _get_discount_params(params) -> tuple[int | None, int | None]:
    """Lấy discount_min và discount_max từ params. Bỏ qua giá trị 0."""
    discount_min = getattr(params, "discount_min", None)
    discount_max = getattr(params, "discount_max", None)

    # Treat 0 as null (Gemini sends 0 instead of null)
    if discount_min is not None and discount_min <= 0:
        discount_min = None
    if discount_max is not None and discount_max <= 0:
        discount_max = None

    if discount_min is not None or discount_max is not None:
        if discount_min and discount_max:
            logger.info(f"🏷️ [DISCOUNT FILTER] Filtering products with discount {discount_min}% - {discount_max}%")
        elif discount_min:
            logger.info(f"🏷️ [DISCOUNT FILTER] Filtering products with discount >= {discount_min}%")
        else:
            logger.info(f"🏷️ [DISCOUNT FILTER] Filtering products with discount <= {discount_max}%")

    return discount_min, discount_max


def _get_metadata_clauses(params, sql_params: list) -> list[str]:
    """
    HARD FILTER: Gender + Age — lọc trực tiếp ở SQL level.
    Gender tự động include 'unisex' fallback cho men/women.
    Color + Product type → semantic search tự handle qua description.
    """
    clauses = []

    # Gender filter
    gender_val = getattr(params, "gender_by_product", None)
    if gender_val:
        gender_lower = gender_val.lower().strip()
        # Include 'unisex' fallback for men/women
        if gender_lower in ("men", "women"):
            clauses.append("gender_by_product IN (%s, %s)")
            sql_params.extend([gender_lower, "unisex"])
        else:
            clauses.append("gender_by_product = %s")
            sql_params.append(gender_lower)
        logger.info(f"👫 [SQL FILTER] Gender: {gender_val}")

    # Age filter
    age_val = getattr(params, "age_by_product", None)
    if age_val:
        age_lower = age_val.lower().strip()
        clauses.append("age_by_product = %s")
        sql_params.append(age_lower)
        logger.info(f"🎂 [SQL FILTER] Age: {age_val}")

    # Color filter (LIKE match on master_color OR product_color_name)
    color_val = getattr(params, "master_color", None)
    if color_val:
        color_lower = color_val.lower().strip()
        clauses.append("(LOWER(master_color) LIKE %s OR LOWER(product_color_name) LIKE %s)")
        sql_params.extend([f"%{color_lower}%", f"%{color_lower}%"])
        logger.info(f"🎨 [SQL FILTER] Color: {color_val}")

    # Product name filter: resolve synonym → exact match or LIKE fallback
    name_val = getattr(params, "product_name", None)
    if name_val:
        from agent.tools.product_mapping import resolve_product_name, PRODUCT_LINE_MAP

        # Support '/' separator: "Áo lót/Áo bra active" → ["Áo lót", "Áo bra active"]
        name_parts = [p.strip() for p in name_val.split("/") if p.strip()]

        like_parts = []
        for part in name_parts:
            resolved = resolve_product_name(part)
            # DB key → product_line_vn LIKE match (covers sub-categories)
            # VD: 'Quần lót' → matches 'Quần lót', 'Quần lót đùi', 'Quần lót tam giác'
            if resolved in PRODUCT_LINE_MAP:
                like_parts.append("LOWER(product_line_vn) LIKE %s")
                sql_params.append(f"%{resolved.lower()}%")
                logger.info(f"🏷️ [SQL FILTER] Product line: '{part}' → LIKE '%{resolved.lower()}%'")
            else:
                # Fallback: LIKE on product_name
                like_parts.append("LOWER(product_name) LIKE %s")
                sql_params.append(f"%{resolved.lower()}%")
                logger.info(f"🏷️ [SQL FILTER] Product name LIKE: '{part}' → '%{resolved.lower()}%'")

        if like_parts:
            clauses.append(f"({' OR '.join(like_parts)})")

    return clauses


async def build_starrocks_query(params) -> tuple[str, list]:
    """
    Build SQL query với Parameterized Query để tránh SQL Injection.
    Returns: (sql_string, params_list)
    """

    # ============================================================
    # CASE 1: CODE SEARCH
    # ============================================================
    magento_code = getattr(params, "magento_ref_code", None)
    if magento_code:
        sql = """
        SELECT
            internal_ref_code,
            magento_ref_code,
            product_color_code,
            product_name,
            master_color,
            product_image_url_thumbnail,
            product_web_url,
            description_text,
            sale_price,
            original_price,
            discount_amount,
            ROUND(CASE WHEN original_price > 0 THEN ((original_price - sale_price) / original_price * 100) ELSE 0 END, 0) as discount_percent,
            age_by_product,
            gender_by_product,
            product_line_vn,
            quantity_sold,
            size_scale,
            1.0 as similarity_score
        FROM shared_source.magento_product_dimension_with_text_embedding
        WHERE internal_ref_code = %s OR magento_ref_code = %s
        """
        return sql, [magento_code, magento_code]


    # ============================================================
    # CASE 2: DISCOVERY — Hàng mới / Bán chạy (Direct SQL, no embedding)
    # Khác với price/gender filter: discovery cần scan TOÀN BỘ bảng
    # vì top 100 vector results gần như không chứa new/best_seller
    # ============================================================
    discovery_mode = getattr(params, "discovery_mode", None)
    if discovery_mode:
        discovery_mode = discovery_mode.lower().strip()
        sql_params: list = []

        # Metadata filters (gender + age)
        where_clauses = _get_metadata_clauses(params, sql_params)



        # Price filters
        where_clauses.extend(_get_price_clauses(params, sql_params))

        # Discovery-specific WHERE + ORDER
        if discovery_mode == "new":
            where_clauses.append("is_new_product = 1")
            order_by = "quantity_sold DESC, magento_ref_code"
            logger.info("🆕 [DISCOVERY] New products, filters=%s", where_clauses)
        elif discovery_mode == "best_seller":
            where_clauses.append("quantity_sold > 0")
            order_by = "quantity_sold DESC, magento_ref_code"
            logger.info("🔥 [DISCOVERY] Best sellers, filters=%s", where_clauses)
        else:
            discovery_mode = None

        if discovery_mode:
            where_str = " AND ".join(where_clauses) if where_clauses else "1=1"
            sql = f"""
            SELECT
                internal_ref_code,
                magento_ref_code,
                product_color_code,
                product_name,
                master_color,
                product_image_url_thumbnail,
                product_web_url,
                sale_price,
                original_price,
                discount_amount,
                ROUND(CASE WHEN original_price > 0 THEN ((original_price - sale_price) / original_price * 100) ELSE 0 END, 0) as discount_percent,
                age_by_product,
                gender_by_product,
                product_line_vn,
                quantity_sold,
                description_text,
                size_scale
            FROM shared_source.magento_product_dimension_with_text_embedding
            WHERE {where_str}
            ORDER BY {order_by}
            LIMIT 20
            """
            logger.info("⚡ [DISCOVERY] Direct SQL — no embedding")
            return sql, sql_params


    # ============================================================
    # CASE 3: STRUCTURED SQL SEARCH (No Embedding)
    # Dùng structured filters: product_name, gender, color, price...
    # ============================================================
    sql_params: list = []

    # 1. Metadata filters (gender, age, color, product_name LIKE)
    metadata_clauses = _get_metadata_clauses(params, sql_params)

    # 2. Price filters
    price_clauses = _get_price_clauses(params, sql_params)

    all_clauses = metadata_clauses + price_clauses

    # 3. Discount filters
    discount_min, discount_max = _get_discount_params(params)

    if discount_min is not None or discount_max is not None:
        all_clauses.append("sale_price < original_price")  # Ensure has discount
        if discount_min is not None:
            all_clauses.append(
                "ROUND(CASE WHEN original_price > 0 THEN ((original_price - sale_price) / original_price * 100) ELSE 0 END, 0) >= %s"
            )
            sql_params.append(discount_min)
        if discount_max is not None:
            all_clauses.append(
                "ROUND(CASE WHEN original_price > 0 THEN ((original_price - sale_price) / original_price * 100) ELSE 0 END, 0) <= %s"
            )
            sql_params.append(discount_max)

    # 4. Fallback: nếu không có filter nào → dùng description LIKE
    if not all_clauses:
        desc_text = getattr(params, "description", None)
        if desc_text:
            # Tách keywords từ description để LIKE match
            keywords = [w.strip() for w in desc_text.split() if len(w.strip()) > 1]
            if keywords:
                like_parts = []
                for kw in keywords[:5]:  # Max 5 keywords to avoid slow query
                    like_parts.append("(LOWER(product_name) LIKE %s OR LOWER(description_text) LIKE %s)")
                    sql_params.extend([f"%{kw.lower()}%", f"%{kw.lower()}%"])
                all_clauses.append(f"({' AND '.join(like_parts)})")
                logger.info("🔍 [FALLBACK LIKE] Using description keywords: %s", keywords[:5])

    where_str = " AND ".join(all_clauses) if all_clauses else "1=1"

    sql = f"""
    SELECT
        internal_ref_code,
        magento_ref_code,
        product_color_code,
        product_name,
        master_color,
        product_image_url_thumbnail,
        product_web_url,
        sale_price,
        original_price,
        discount_amount,
        ROUND(CASE WHEN original_price > 0 THEN ((original_price - sale_price) / original_price * 100) ELSE 0 END, 0) as discount_percent,
        age_by_product,
        gender_by_product,
        product_line_vn,
        product_line_en,
        description_text,
        size_scale,
        quantity_sold,
        is_new_product
    FROM shared_source.magento_product_dimension_with_text_embedding
    WHERE {where_str}
    ORDER BY quantity_sold DESC, magento_ref_code
    LIMIT 20
    """

    logger.info("⚡ [STRUCTURED SQL] Direct filter search — no embedding needed")
    return sql, sql_params
