from fastapi import APIRouter, HTTPException, Request, Depends
from model.product import ProductDatabaseModel
from MongoDBConnection import MONGO_URI, DB_NAME
from utils.auth_helper import requires_permission
from utils.turnstile_helper import verify_turnstile

router = APIRouter()

db_model = ProductDatabaseModel(
    db_uri=MONGO_URI,
    db_name=DB_NAME,
    collection_name="products"
)


def _format_upload_url(request: Request, value: str) -> str:
    raw = str(value or "").strip()
    if not raw:
        return ""

    if raw.startswith("http"):
        return raw

    raw = raw.lstrip("/")
    return f"{request.base_url}uploads/upload_img/{raw}"


def _normalize_update_payload(update_data: dict) -> dict:
    normalized = dict(update_data)

    if "id" in normalized:
        del normalized["id"]

    normalized["description"] = normalized.get("description", "") or ""
    normalized["colors"] = normalized.get("colors", []) or []
    normalized["styles"] = normalized.get("styles", []) or []
    normalized["variants"] = normalized.get("variants", []) or []
    normalized["shippingRates"] = normalized.get("shippingRates", []) or []
    normalized["sizeGuide"] = normalized.get("sizeGuide", []) or []

    return normalized


@router.get("/products")
async def get_public_products(request: Request, categoryId: str = None):
    try:
        query = {}
        if categoryId:
            query["categoryName"] = categoryId

        products_cursor = db_model.collection.find(query)

        result_list = []
        for p in products_cursor:
            images = p.get("images", [])
            img_name = images[0] if len(images) > 0 else ""

            image_url = _format_upload_url(request, img_name) if img_name else ""

            item = {
                "id": p.get("productId", ""),
                "title": p.get("title", ""),
                "categoryId": p.get("categoryName", "").lower(),
                "categoryName": p.get("categoryName", ""),
                "price": float(p.get("price", 0)),
                "badge": p.get("badge", ""),
                "badgeColor": p.get("badgeColor", "#3b82f6"),
                "image": image_url
            }
            result_list.append(item)

        return {
            "error": False,
            "data": result_list
        }
    except Exception as e:
        return {"error": True, "message": str(e)}


@router.get("/products/{product_id}")
async def get_product_detail(request: Request, product_id: str):
    try:
        p = db_model.collection.find_one({"productId": product_id})

        if not p:
            raise HTTPException(status_code=404, detail="Product not found")

        raw_images = p.get("images", [])
        formatted_images = []
        for img in raw_images:
            formatted_images.append(_format_upload_url(request, img) if img else "")

        formatted_images = [img for img in formatted_images if img]

        if not formatted_images:
            formatted_images = ["https://via.placeholder.com/500"]

        raw_styles = p.get("styles", []) or []
        formatted_styles = []
        for style in raw_styles:
            formatted_styles.append({
                "name": style.get("name", ""),
                "thumbnail": _format_upload_url(request, style.get("thumbnail", ""))
            })

        item = {
            "id": p.get("productId", ""),
            "title": p.get("title", ""),
            "categoryId": p.get("categoryName", "").lower(),
            "categoryName": p.get("categoryName", ""),
            "price": float(p.get("price", 0)),
            "description": p.get("description", ""),
            "badge": p.get("badge", ""),
            "badgeColor": p.get("badgeColor", "#3b82f6"),
            "images": formatted_images,
            "sizes": p.get("sizes", []),
            "designTemplate": p.get("designTemplate", {
                "width": 4500,
                "height": 5400,
                "dpi": 300
            })
        }

        if p.get("colors"):
            item["colors"] = p.get("colors")

        if formatted_styles:
            item["styles"] = formatted_styles

        if p.get("variants"):
            item["variants"] = p.get("variants")

        if p.get("shippingRates"):
            item["shippingRates"] = p.get("shippingRates")

        if p.get("sizeGuide"):
            item["sizeGuide"] = p.get("sizeGuide")

        return {
            "error": False,
            "data": item
        }
    except HTTPException as he:
        raise he
    except Exception as e:
        return {"error": True, "message": str(e)}


@router.put(
    "/products/{product_id}",
    dependencies=[Depends(verify_turnstile), Depends(requires_permission("product_management"))]
)
async def update_product(product_id: str, request: Request):
    try:
        update_data = await request.json()

        existing_product = db_model.collection.find_one({"productId": product_id})
        if not existing_product:
            raise HTTPException(status_code=404, detail="Không tìm thấy sản phẩm để cập nhật")

        normalized_update_data = _normalize_update_payload(update_data)

        result = db_model.collection.update_one(
            {"productId": product_id},
            {"$set": normalized_update_data}
        )

        if result.modified_count == 0:
            return {"success": True, "message": "Dữ liệu không có thay đổi so với bản cũ"}

        return {
            "success": True,
            "message": "Cập nhật sản phẩm thành công!"
        }
    except HTTPException as he:
        raise he
    except Exception as e:
        return {"success": False, "message": f"Lỗi hệ thống: {str(e)}"}


@router.delete(
    "/products/{product_id}",
    dependencies=[Depends(verify_turnstile), Depends(requires_permission("product_management"))]
)
async def delete_product(product_id: str):
    try:
        result = db_model.collection.delete_one({"productId": product_id})

        if result.deleted_count == 0:
            raise HTTPException(status_code=404, detail="Sản phẩm không tồn tại hoặc đã bị xóa trước đó")

        return {
            "success": True,
            "message": f"Đã xóa vĩnh viễn sản phẩm {product_id}!"
        }
    except HTTPException as he:
        raise he
    except Exception as e:
        return {"success": False, "message": f"Lỗi khi xóa: {str(e)}"}