"""
Product Performance API Route
Provides real-time product data from StarRocks for the Product Performance dashboard.
"""

import logging
from typing import Optional

from fastapi import APIRouter, Query
from fastapi.responses import JSONResponse

from common.starrocks_connection import get_db_connection
from agent.tools.product_mapping import resolve_color, resolve_product_name, SYNONYM_TO_DB

logger = logging.getLogger(__name__)
router = APIRouter()

TABLE_NAME = "shared_source.magento_product_dimension_with_text_embedding"


@router.get("/api/products/overview", summary="Product catalog KPI overview")
async def products_overview():
    """Return aggregate KPIs for the product catalog."""
    db = get_db_connection()
    try:
        rows = await db.execute_query_async(f"""
            SELECT
                COUNT(DISTINCT internal_ref_code)  AS total_products,
                COUNT(DISTINCT product_line_vn)     AS total_lines,
                COUNT(DISTINCT gender_by_product)   AS total_genders,
                ROUND(MIN(sale_price))              AS min_price,
                ROUND(MAX(sale_price))              AS max_price,
                ROUND(AVG(sale_price))              AS avg_price,
                SUM(CASE WHEN sale_price < original_price AND original_price > 0 THEN 1 ELSE 0 END) AS discounted_count,
                SUM(CASE WHEN is_new_product = 1 THEN 1 ELSE 0 END) AS new_count,
                SUM(CASE WHEN quantity_sold > 0 THEN 1 ELSE 0 END)  AS selling_count,
                SUM(quantity_sold)                   AS total_sold
            FROM {TABLE_NAME}
        """)

        # Get top product lines breakdown
        lines = await db.execute_query_async(f"""
            SELECT
                product_line_vn,
                COUNT(DISTINCT internal_ref_code) AS count,
                ROUND(AVG(sale_price))            AS avg_price,
                SUM(quantity_sold)                AS total_sold
            FROM {TABLE_NAME}
            WHERE product_line_vn IS NOT NULL AND product_line_vn != ''
            GROUP BY product_line_vn
            ORDER BY count DESC
            LIMIT 15
        """)

        # Gender breakdown
        genders = await db.execute_query_async(f"""
            SELECT
                gender_by_product,
                COUNT(DISTINCT internal_ref_code) AS count
            FROM {TABLE_NAME}
            WHERE gender_by_product IS NOT NULL AND gender_by_product != ''
            GROUP BY gender_by_product
            ORDER BY count DESC
        """)

        stats = rows[0] if rows else {}

        return {
            "status": "success",
            "stats": {
                "total_products": stats.get("total_products", 0),
                "total_lines": stats.get("total_lines", 0),
                "min_price": stats.get("min_price", 0),
                "max_price": stats.get("max_price", 0),
                "avg_price": stats.get("avg_price", 0),
                "discounted_count": stats.get("discounted_count", 0),
                "new_count": stats.get("new_count", 0),
                "selling_count": stats.get("selling_count", 0),
                "total_sold": stats.get("total_sold", 0),
            },
            "product_lines": lines,
            "genders": genders,
        }
    except Exception as e:
        logger.error(f"❌ Product overview error: {e}")
        return JSONResponse(
            status_code=500,
            content={"status": "error", "message": str(e)},
        )


@router.get("/api/products/list", summary="Product listing grouped by internal_ref_code")
async def products_list(
    sort: str = Query("quantity_sold", description="Sort field"),
    order: str = Query("desc", description="Sort order: asc or desc"),
    gender: Optional[str] = Query(None, description="Filter by gender"),
    age: Optional[str] = Query(None, description="Filter by age group"),
    product_line: Optional[str] = Query(None, description="Filter by product line"),
    search: Optional[str] = Query(None, description="Search by name or code"),
    color: Optional[str] = Query(None, description="Filter by master_color (user-friendly term)"),
    is_new: Optional[bool] = Query(None, description="Filter new products"),
    has_discount: Optional[bool] = Query(None, description="Filter discounted"),
    limit: int = Query(50, ge=1, le=500),
    offset: int = Query(0, ge=0),
):
    """Return paginated product listing grouped by internal_ref_code."""
    db = get_db_connection()

    # Build WHERE clauses
    clauses = []
    params = []
    use_relevance = False  # Smart search ranking flag
    search_lower = ""
    resolved_name_lower = ""

    if gender:
        clauses.append("gender_by_product = %s")
        params.append(gender.lower())
    if age:
        clauses.append("age_by_product = %s")
        params.append(age.lower())
    if product_line:
        clauses.append("LOWER(product_line_vn) LIKE %s")
        params.append(f"%{product_line.lower()}%")
    if search:
        # Resolve synonym: "áo thun" → "Áo phông", "quần bò" → "Quần jean"
        resolved_name = resolve_product_name(search)
        search_lower = search.lower()
        resolved_name_lower = resolved_name.lower()
        use_relevance = True  # Enable relevance sorting

        # Check if search matches a product_line synonym
        matched_line = SYNONYM_TO_DB.get(search_lower)

        if matched_line and resolved_name_lower != search_lower:
            clauses.append(
                "(LOWER(product_name) LIKE %s OR LOWER(product_name) LIKE %s "
                "OR LOWER(product_line_vn) = %s "
                "OR internal_ref_code LIKE %s OR magento_ref_code LIKE %s)"
            )
            params.extend([
                f"%{search_lower}%",
                f"%{resolved_name_lower}%",
                matched_line.lower(),
                f"%{search.upper()}%",
                f"%{search.upper()}%",
            ])
            logger.info(f"🔍 Search mapped: '{search}' → '{resolved_name}' (line: {matched_line})")
        else:
            clauses.append(
                "(LOWER(product_name) LIKE %s OR internal_ref_code LIKE %s OR magento_ref_code LIKE %s)"
            )
            params.extend([f"%{search_lower}%", f"%{search.upper()}%", f"%{search.upper()}%"])
    if is_new is True:
        clauses.append("is_new_product = 1")
    if has_discount is True:
        clauses.append("sale_price < original_price AND original_price > 0")
    if color:
        db_color = resolve_color(color)
        if db_color:
            clauses.append("master_color = %s")
            params.append(db_color)
        else:
            clauses.append("LOWER(master_color) LIKE %s")
            params.append(f"%{color.lower()}%")

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

    # ── Smart Relevance Ranking ──
    # Build a CASE-based relevance score when search is active
    if use_relevance and sort in ("quantity_sold", "relevance"):
        # Tiered scoring: exact SKU > prefix SKU > exact name > startsWith > contains > partial
        relevance_expr = f"""
            MAX(
                CASE
                    WHEN UPPER(internal_ref_code) = %s THEN 100
                    WHEN UPPER(internal_ref_code) LIKE %s THEN 90
                    WHEN LOWER(product_name) = %s THEN 85
                    WHEN LOWER(product_name) LIKE %s THEN 70
                    WHEN LOWER(product_name) LIKE %s THEN 50
                    WHEN LOWER(product_line_vn) = %s THEN 40
                    ELSE 30
                END
            )"""
        relevance_params = [
            search.upper(),                  # exact SKU
            f"{search.upper()}%",            # SKU prefix
            search_lower,                    # exact name
            f"{search_lower}%",              # name starts with
            f"%{search_lower}%",             # name contains
            search_lower,                    # exact product_line
        ]
        order_clause = f"relevance_score DESC, quantity_sold DESC"
        sort_field = "relevance"
    else:
        relevance_expr = None
        relevance_params = []
        allowed_sorts = {
            "quantity_sold", "sale_price", "original_price", "product_name",
            "discount_percent", "internal_ref_code",
        }
        if sort not in allowed_sorts:
            sort = "quantity_sold"
        order_dir = "ASC" if order.lower() == "asc" else "DESC"
        order_clause = f"{sort} {order_dir}"
        sort_field = sort

    try:
        # Get total count (grouped)
        count_rows = await db.execute_query_async(
            f"SELECT COUNT(DISTINCT internal_ref_code) AS total FROM {TABLE_NAME} WHERE {where_str}",
            params=tuple(params) if params else None,
        )
        total = count_rows[0]["total"] if count_rows else 0

        # Build SELECT with optional relevance score
        relevance_col = f",\n                {relevance_expr} AS relevance_score" if relevance_expr else ""
        all_params = params + relevance_params + [limit, offset]

        products = await db.execute_query_async(
            f"""
            SELECT
                internal_ref_code,
                ANY_VALUE(product_name)                  AS product_name,
                ANY_VALUE(product_image_url_thumbnail)    AS product_image_url_thumbnail,
                ANY_VALUE(product_web_url)                AS product_web_url,
                MIN(sale_price)                           AS sale_price,
                MAX(original_price)                       AS original_price,
                ROUND(CASE WHEN MAX(original_price) > 0
                    THEN ((MAX(original_price) - MIN(sale_price)) / MAX(original_price) * 100)
                    ELSE 0 END, 0)                        AS discount_percent,
                ANY_VALUE(age_by_product)                 AS age_by_product,
                ANY_VALUE(gender_by_product)              AS gender_by_product,
                ANY_VALUE(product_line_vn)                AS product_line_vn,
                MAX(quantity_sold)                        AS quantity_sold,
                MAX(is_new_product)                       AS is_new_product,
                ANY_VALUE(size_scale)                     AS size_scale,
                COUNT(DISTINCT product_color_code)        AS color_count,
                GROUP_CONCAT(DISTINCT product_color_code) AS color_codes,
                GROUP_CONCAT(DISTINCT master_color)       AS colors{relevance_col}
            FROM {TABLE_NAME}
            WHERE {where_str}
            GROUP BY internal_ref_code
            ORDER BY {order_clause}
            LIMIT %s OFFSET %s
            """,
            params=tuple(all_params),
        )

        return {
            "status": "success",
            "total": total,
            "limit": limit,
            "offset": offset,
            "sort": sort_field,
            "products": products,
        }
    except Exception as e:
        logger.error(f"❌ Product list error: {e}")
        return JSONResponse(
            status_code=500,
            content={"status": "error", "message": str(e)},
        )


@router.get("/api/products/colors", summary="Color variants for a product")
async def products_colors(
    code: str = Query(..., description="internal_ref_code"),
):
    """Return all color variants for a given internal_ref_code."""
    db = get_db_connection()
    try:
        variants = await db.execute_query_async(
            f"""
            SELECT
                product_color_code,
                master_color,
                product_color_name,
                product_image_url_thumbnail,
                product_web_url,
                sale_price,
                original_price,
                quantity_sold,
                size_scale
            FROM {TABLE_NAME}
            WHERE internal_ref_code = %s
            ORDER BY quantity_sold DESC
            """,
            params=(code,),
        )
        return {"status": "success", "variants": variants}
    except Exception as e:
        logger.error(f"❌ Product colors error: {e}")
        return JSONResponse(
            status_code=500,
            content={"status": "error", "message": str(e)},
        )


@router.get("/api/products/filters", summary="Available filter options")
async def products_filters():
    """Return all available filter values for color, product_line, age, season."""
    db = get_db_connection()
    try:
        colors = await db.execute_query_async(f"""
            SELECT master_color, COUNT(DISTINCT internal_ref_code) AS cnt
            FROM {TABLE_NAME}
            WHERE master_color IS NOT NULL AND master_color != ''
            GROUP BY master_color ORDER BY cnt DESC
        """)
        lines = await db.execute_query_async(f"""
            SELECT product_line_vn, COUNT(DISTINCT internal_ref_code) AS cnt
            FROM {TABLE_NAME}
            WHERE product_line_vn IS NOT NULL AND product_line_vn != ''
            GROUP BY product_line_vn ORDER BY cnt DESC
        """)
        ages = await db.execute_query_async(f"""
            SELECT age_by_product, COUNT(DISTINCT internal_ref_code) AS cnt
            FROM {TABLE_NAME}
            WHERE age_by_product IS NOT NULL AND age_by_product != ''
            GROUP BY age_by_product ORDER BY cnt DESC
        """)
        seasons = await db.execute_query_async(f"""
            SELECT season, COUNT(DISTINCT internal_ref_code) AS cnt
            FROM {TABLE_NAME}
            WHERE season IS NOT NULL AND season != ''
            GROUP BY season ORDER BY cnt DESC
        """)
        return {
            "status": "success",
            "colors": colors,
            "product_lines": lines,
            "ages": ages,
            "seasons": seasons,
        }
    except Exception as e:
        logger.error(f"❌ Product filters error: {e}")
        return JSONResponse(
            status_code=500,
            content={"status": "error", "message": str(e)},
        )
