"""
SKU Search Tool — LangChain @tool cho AI gọi.
Tìm sản phẩm CANIFA theo mã SKU (magento_ref_code / internal_ref_code / product_color_code).

Logic lấy Y HỆT từ chatbot data_retrieval_tool.py → product_search_helpers.py:
  - CTE resolved_family: match trên internal_ref_code, magento_ref_code, product_color_code
  - Subsequence LIKE pattern: user nhập thiếu ký tự vẫn match
  - Color suffix parsing: "6OT24S001-SG055" → internal="6OT24S001", suffix="SG055"
  - Explicit master_color filter qua SQL LIKE
"""

import json
import logging
import time

from langchain_core.tools import tool
from pydantic import BaseModel, Field

from common.starrocks_connection import get_db_connection

logger = logging.getLogger(__name__)

PRODUCT_SEARCH_TABLE = "shared_source.magento_product_dimension_with_text_embedding"

SELECT_COLUMNS = """
    magento_ref_code,
    product_color_code,
    product_name,
    master_color,
    product_color_name,
    product_image_url_thumbnail,
    product_web_url,
    description_text_full,
    sale_price,
    original_price,
    discount_amount,
    ROUND(((original_price - sale_price) / original_price * 100), 0) as discount_percent,
    age_by_product,
    gender_by_product,
    product_line_vn,
    quantity_sold,
    size_scale,
    1.0 as similarity_score
"""


# ═══════════════════════════════════════════════
# Pydantic Schema — AI sẽ fill vào đây
# ═══════════════════════════════════════════════
class SkuSearchInput(BaseModel):
    """Schema cho SKU search: mã sản phẩm + tuỳ chọn lọc màu."""

    model_config = {"extra": "forbid"}

    sku_code: str = Field(
        description=(
            "Mã sản phẩm (SKU) cần tìm. "
            "VD: '6OT24S001-SG055', '6OT24S001', 'TS092'. "
            "Nhập CHÍNH XÁC mã khách cung cấp, bao gồm cả phần sau dấu gạch ngang nếu có."
        )
    )
    master_color: str | None = Field(
        default=None,
        description=(
            "Màu sắc sản phẩm nếu khách có nói rõ màu. "
            "VD: 'đỏ', 'trắng', 'xanh'. Để null nếu khách không nhắc đến màu."
        ),
    )


# ═══════════════════════════════════════════════
# Code Parsing Helpers (từ product_search_helpers.py)
# ═══════════════════════════════════════════════
def _parse_code_search_input(raw_code: str) -> tuple[str, str | None]:
    """Chuẩn hoá mã user gửi và tách phần internal_ref_code / suffix nếu có."""
    normalized = str(raw_code or "").strip().upper().replace(" ", "")
    if "-" not in normalized:
        return normalized, None
    internal_ref_code, suffix_code = normalized.split("-", 1)
    return internal_ref_code, suffix_code or None


def _build_code_subsequence_pattern(raw_code: str) -> str:
    """
    Build LIKE pattern giữ nguyên thứ tự ký tự.
    Dùng cho trường hợp user nhập thiếu 1 ký tự ở giữa mã nhưng vẫn muốn match ra full code.
    VD: 6ST25W05 -> %6%S%T%2%5%W%0%5%
    """
    normalized = str(raw_code or "").strip().upper().replace(" ", "").replace("-", "")
    if not normalized:
        return "%"
    return "%" + "%".join(normalized) + "%"


# ═══════════════════════════════════════════════
# SQL Builder — Search thẳng bằng magento_ref_code
# Input: 6TS25S003-SB055 → base=6TS25S003 → lấy TẤT CẢ variants
# Input: 6TS25S003        → trực tiếp magento_ref_code match
# ═══════════════════════════════════════════════
def _build_sku_query(sku_code: str) -> tuple[str, list]:
    """
    Search trực tiếp bằng magento_ref_code.
    - User gửi '6TS25S003-SB055' → base_code='6TS25S003' → tìm tất cả variants của magento 6TS25S003
    - User gửi '6TS25S003'       → tìm trực tiếp magento_ref_code = 6TS25S003
    - Nếu exact match = 0, fallback sang product_color_code match
    Color filter xử lý ở Python sau.
    """
    normalized_code = str(sku_code).strip().upper().replace(" ", "")
    base_code, suffix_code = _parse_code_search_input(normalized_code)

    # Params: exact magento match + product_color_code match
    sql_params = [
        base_code,                  # UPPER(magento_ref_code) = %s          (base code)
        normalized_code,            # UPPER(magento_ref_code) = %s          (full code)
        normalized_code,            # UPPER(product_color_code) = %s        (full code exact)
        f"{base_code}-%",           # UPPER(product_color_code) LIKE %s     (all variants)
    ]

    logger.info(
        "🏷️ [SKU SEARCH] input=%s, base_magento=%s, suffix=%s",
        normalized_code, base_code, suffix_code,
    )

    sql = f"""
    SELECT
        {SELECT_COLUMNS}
    FROM {PRODUCT_SEARCH_TABLE}
    WHERE UPPER(magento_ref_code) = %s
       OR UPPER(magento_ref_code) = %s
       OR UPPER(product_color_code) = %s
       OR UPPER(product_color_code) LIKE %s
    """
    return sql, sql_params


# ═══════════════════════════════════════════════
# Format Output
# ═══════════════════════════════════════════════
def _format_products(products: list) -> list[dict]:
    """Format output cho AI đọc."""
    formatted = []
    seen_color_codes = set()

    for p in products:
        color_code = p.get("product_color_code", "")
        if color_code in seen_color_codes:
            continue
        seen_color_codes.add(color_code)

        sale = float(p.get("sale_price") or 0)
        orig = float(p.get("original_price") or 0)
        has_discount = sale < orig and orig > 0
        disc_pct = int(p.get("discount_percent") or 0)

        formatted.append({
            "sku": p.get("magento_ref_code", ""),
            "sku_color": p.get("product_color_code", ""),
            "name": p.get("product_name", ""),
            "price": int(sale),
            "original_price": int(orig),
            "discount": f"-{disc_pct}%" if has_discount else None,
            "color": p.get("master_color", ""),
            "color_name": p.get("product_color_name", ""),
            "gender": p.get("gender_by_product", ""),
            "product_line": p.get("product_line_vn", ""),
            "image": p.get("product_image_url_thumbnail", ""),
            "url": p.get("product_web_url", ""),
            "sizes": p.get("size_scale", ""),
            "description": (p.get("description_text_full") or "")[:300],
            "quantity_sold": int(p.get("quantity_sold") or 0),
        })
    return formatted


# ═══════════════════════════════════════════════
# Tool Entry Point
# ═══════════════════════════════════════════════
@tool(args_schema=SkuSearchInput)
async def sku_search_tool(
    sku_code: str,
    master_color: str | None = None,
) -> str:
    """
    Tìm sản phẩm CANIFA theo mã SKU.
    Sử dụng CTE resolved_family để tìm tất cả variants cùng mã gốc.
    Trả về thông tin chi tiết: tên, giá, màu, size, link mua hàng, và các biến thể.

    Nếu master_color được chỉ định:
    - Lọc ra các variant có màu đó
    - Nếu KHÔNG có màu đó → trả danh sách tất cả màu available để AI thông báo cho user
    """
    start = time.time()

    db = get_db_connection()

    try:
        # LUÔN lấy TẤT CẢ variants (không filter color ở SQL)
        sql, params = _build_sku_query(sku_code)
        all_products = await db.execute_query_async(sql, params=tuple(params))

        elapsed_ms = round((time.time() - start) * 1000, 2)

        logger.info(
            "🔍 [SKU SEARCH] code='%s', color='%s' | all_variants=%d | time=%.2fms",
            sku_code, master_color, len(all_products), elapsed_ms,
        )

        # Format tất cả products
        all_formatted = _format_products(all_products)

        # Lấy danh sách tất cả màu unique
        available_colors = sorted(set(
            p["color"] for p in all_formatted if p.get("color")
        ))

        # Nếu user YÊU CẦU lọc màu → filter ở Python
        color_matched = []
        color_filter_applied = False
        color_found = True

        if master_color:
            color_filter_applied = True
            color_lower = master_color.lower().strip()
            for p in all_formatted:
                p_color = (p.get("color") or "").lower()
                p_color_name = (p.get("color_name") or "").lower()
                if color_lower in p_color or color_lower in p_color_name:
                    color_matched.append(p)

            if color_matched:
                color_found = True
                logger.info("🎨 [SKU SEARCH] Color '%s' matched %d/%d variants", master_color, len(color_matched), len(all_formatted))
            else:
                color_found = False
                logger.info("🎨 [SKU SEARCH] Color '%s' NOT FOUND. Available: %s", master_color, available_colors)

                # ═══ Build Recommendation for Exception ═══
                recommend_colors = []
                seen_codes = set()
                for p in all_formatted:
                    c_code = p.get("sku_color")
                    if c_code and c_code not in seen_codes:
                        seen_codes.add(c_code)
                        recommend_colors.append({
                            "product_color_code": c_code,
                            "master_color": p.get("color", ""),
                            "magento_ref_code": p.get("sku", "")
                        })

                # Kiểm tra xem user hỏi gốc (6TS) hay hỏi nhánh cụ thể (6TS-xxx)
                normalized_code = str(sku_code).strip().upper().replace(" ", "")
                _, suffix_code = _parse_code_search_input(normalized_code)

                if suffix_code:
                    # User có suffix: '6TS25S003-SB055' màu đen
                    actual_color = "Không xác định"
                    for p in all_formatted:
                        if p.get("sku_color", "").upper() == normalized_code:
                            actual_color = p.get("color", "")
                            break

                    msg = f"Mã product_color_code {sku_code} thực tế có master_color là '{actual_color}', không phải màu '{master_color}'. Các master_color hiện có: {', '.join(available_colors)}."
                    color_exception = {
                        "requested_color": master_color,
                        "matched_product_color_code": sku_code,
                        "matched_master_color": actual_color,
                        "recommend_colors": recommend_colors,
                        "message": msg
                    }
                else:
                    msg = f"Mã magento_ref_code {sku_code} KHÔNG có master_color '{master_color}'. Các master_color hiện có: {', '.join(available_colors)}."
                    color_exception = {
                        "requested_color": master_color,
                        "matched_magento_ref_code": sku_code,
                        "recommend_colors": recommend_colors,
                        "message": msg
                    }

        # ═══ Build response ═══
        if color_filter_applied and not color_found:
            # Màu không tồn tại → trả TẤT CẢ products + color_exception
            return json.dumps({
                "status": "success",
                "sku_queried": sku_code,
                "color_filter": master_color,
                "color_found": False,
                "color_exception": color_exception,
                "message": color_exception["message"],
                "available_colors": available_colors,
                "total_variants": len(all_products),
                "unique_colors": len(all_formatted),
                "elapsed_ms": elapsed_ms,
                "products": all_formatted,
            }, ensure_ascii=False, default=str)

        elif color_filter_applied and color_found:
            # Màu tìm thấy → trả chỉ products đúng màu + danh sách màu khác
            return json.dumps({
                "status": "success",
                "sku_queried": sku_code,
                "color_filter": master_color,
                "color_found": True,
                "matched_count": len(color_matched),
                "available_colors": available_colors,
                "total_variants": len(all_products),
                "unique_colors": len(all_formatted),
                "elapsed_ms": elapsed_ms,
                "products": color_matched,
            }, ensure_ascii=False, default=str)

        else:
            # Không filter màu → trả tất cả
            return json.dumps({
                "status": "success",
                "sku_queried": sku_code,
                "color_filter": None,
                "available_colors": available_colors,
                "total_variants": len(all_products),
                "unique_colors": len(all_formatted),
                "elapsed_ms": elapsed_ms,
                "products": all_formatted,
            }, ensure_ascii=False, default=str)

    except Exception as e:
        logger.error("❌ SKU Search tool error: %s", e)
        return json.dumps({"status": "error", "message": str(e)})
