from typing import List, Optional
from fastapi import APIRouter, Query, status
from pydantic import BaseModel
from bson import ObjectId
from app.db.db import get_col

router = APIRouter(prefix="/search", tags=["search"])


class VariantItem(BaseModel):
    variant_id: str
    sku: Optional[str]
    price: Optional[float]
    offer_price: Optional[float]


class SearchResponseItem(BaseModel):
    product_id: str
    name: str
    url: Optional[str]
    image: Optional[str]
    description: Optional[str]
    category: Optional[str]
    sub_category: Optional[str]
    variants: Optional[List[VariantItem]]


# ------------------------ Search API -------------------------------

@router.get("/", response_model=List[SearchResponseItem], status_code=status.HTTP_200_OK)
def search_products(
    query: str = Query(..., min_length=1),
    page: int = Query(1, ge=1),
    limit: int = Query(10, ge=1, le=200),
    sort: Optional[str] = Query(
        "newest",
        description="Sort options: newest, price_low, price_high, name_asc, name_desc"
    ),
):
    products_col = get_col("products")
    categories_col = get_col("categories")
    variants_col = get_col("productvariants")

    skip = (page - 1) * limit

    # Case-insensitive match
    regex = {"$regex": query, "$options": "i"}

    # 1️⃣ Category/Subcategory matches
    matched_categories = list(categories_col.find({"category_name": regex}))
    matched_category_ids = [cat["_id"] for cat in matched_categories]

    # 2️⃣ Variant matches (search in variant name / SKU)
    variant_matches = list(
        variants_col.find(
            {
                "$or": [
                    {"variant_name": regex},
                    {"sku": regex},
                ]
            },
            {"product_id": 1}
        )
    )
    variant_product_ids = [vm["product_id"] for vm in variant_matches]

    # 3️⃣ Build search filter
    search_filter = {
        "$or": [
            {"name": regex},
            {"description": regex},
            {"category": {"$in": matched_category_ids}},
            {"sub_category": {"$in": matched_category_ids}},
            {"type": regex},
            {"sub_category": {"$in": matched_category_ids}},
            {"_id": {"$in": variant_product_ids}},
        ]
    }

    # 4️⃣ Sorting logic
    sort_option = {
        "newest": ("createdAt", -1),
        "price_low": ("min_price", 1),
        "price_high": ("min_price", -1),
        "name_asc": ("name", 1),
        "name_desc": ("name", -1),
    }.get(sort, ("createdAt", -1))

    sort_field, sort_order = sort_option

    # 5️⃣ Query products
    product_docs = list(
        products_col.find(search_filter)
        .sort(sort_field, sort_order)
        .skip(skip)
        .limit(limit)
    )

    results = []

    for doc in product_docs:
        # Fetch variants for the product
        variants = list(
            variants_col.find(
                {"product_id": doc["_id"]},
                {"sku": 1, "price": 1, "offer_price": 1}
            )
        )

        # Convert variants
        variant_items = [
            VariantItem(
                variant_id=str(v["_id"]),
                sku=v.get("sku"),
                price=v.get("price"),
                offer_price=v.get("offer_price"),
            )
            for v in variants
        ]

        # Category name
        category_name = None
        if "category" in doc and isinstance(doc["category"], ObjectId):
            cat = categories_col.find_one({"_id": doc["category"]})
            if cat:
                category_name = cat.get("category_name")

        # Sub-category name
        sub_category_name = None
        if "sub_category" in doc and isinstance(doc["sub_category"], ObjectId):
            sub_cat = categories_col.find_one({"_id": doc["sub_category"]})
            if sub_cat:
                sub_category_name = sub_cat.get("category_name")

        results.append(
            SearchResponseItem(
                product_id=str(doc["_id"]),
                name=doc.get("name"),
                url=doc.get("product_url"),
                image=doc.get("image"),
                type=doc.get("type"),
                description=doc.get("description"),
                category=category_name,
                sub_category=sub_category_name,
                variants=variant_items,
            )
        )

    return results

@router.get("/suggestions", status_code=200)
def search_suggestions(
    query: str = Query(..., min_length=1),
    limit: int = Query(5, ge=1, le=20),
):
    products_col = get_col("products")

    regex = {"$regex": f"^{query}", "$options": "i"}

    suggestions = (
        products_col.find({"name": regex}, {"name": 1})
        .sort("name", 1)
        .limit(limit)
    )

    return [s["name"] for s in suggestions]
