"""前台商品评价路由"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func

from app.api.deps import get_db, get_tenant_by_domain
from app.core.models.review import ProductReview
from app.core.models.product import Product
from app.api.routers.store.auth import get_current_customer
from app.core.models.customer import Customer

router = APIRouter(prefix="/store/reviews", tags=["前台评价"])


class ReviewIn(BaseModel):
    product_id: int
    rating:     int   = Field(..., ge=1, le=5)
    content:    str   = Field(..., min_length=5, max_length=500)
    images:     List[str] = []
    variant:    Optional[str] = None


@router.get("/product/{product_id}", summary="商品评价列表（公开）")
async def list_reviews(
    product_id: int,
    page:       int = Query(1, ge=1),
    page_size:  int = Query(10, ge=1, le=50),
    rating:     Optional[int] = Query(None, ge=1, le=5),
    tid:        int = Depends(get_tenant_by_domain),
    db:         AsyncSession = Depends(get_db),
):
    tenant_id = tid
    q = select(ProductReview).where(
        ProductReview.product_id == product_id,
        ProductReview.tenant_id  == tenant_id,
        ProductReview.status     == "approved",
    )
    if rating:
        q = q.where(ProductReview.rating == rating)

    # 总数
    cnt_r = await db.execute(select(func.count()).select_from(q.subquery()))
    total = cnt_r.scalar()

    # 评分分布
    dist_r = await db.execute(
        select(ProductReview.rating, func.count().label("n"))
        .where(ProductReview.product_id == product_id,
               ProductReview.tenant_id  == tenant_id,
               ProductReview.status     == "approved")
        .group_by(ProductReview.rating)
    )
    dist = {int(row.rating): int(row.n) for row in dist_r.fetchall()}

    avg_r = await db.execute(
        select(func.avg(ProductReview.rating))
        .where(ProductReview.product_id == product_id,
               ProductReview.tenant_id  == tenant_id,
               ProductReview.status     == "approved")
    )
    avg_rating = round(float(avg_r.scalar() or 0), 1)

    q = q.order_by(ProductReview.helpful_count.desc(), ProductReview.created_at.desc()) \
         .offset((page - 1) * page_size).limit(page_size)
    result = await db.execute(q)
    reviews = result.scalars().all()

    return {
        "total":        total,
        "avg_rating":   avg_rating,
        "distribution": dist,
        "items": [
            {
                "id":            r.id,
                "rating":        r.rating,
                "content":       r.content,
                "images":        r.images or [],
                "variant":       r.variant,
                "customer_name": r.customer_name,
                "created_at":    r.created_at,
                "reply":         r.merchant_reply,
                "helpful_count": r.helpful_count,
                "verified":      bool(r.is_verified_purchase),
            }
            for r in reviews
        ],
    }


@router.post("/", summary="提交评价（需顾客登录）")
async def submit_review(
    body:      ReviewIn,
    tid:       int = Depends(get_tenant_by_domain),
    customer:  Customer = Depends(get_current_customer),
    db:        AsyncSession = Depends(get_db),
):
    tenant_id = tid
    # 防重评
    dup = await db.execute(
        select(ProductReview).where(
            ProductReview.product_id == body.product_id,
            ProductReview.customer_id == customer.id,
        )
    )
    if dup.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="您已评价过该商品，不可重复提交")

    # 验证商品
    pr = await db.execute(select(Product).where(Product.id == body.product_id, Product.tenant_id == tenant_id))
    if not pr.scalar_one_or_none():
        raise HTTPException(status_code=404, detail="商品不存在")

    review = ProductReview(
        tenant_id=tenant_id,
        product_id=body.product_id,
        customer_id=customer.id,
        customer_name=customer.name,
        rating=body.rating,
        content=body.content,
        images=body.images or None,
        variant=body.variant,
        status="pending",
    )
    db.add(review)
    await db.commit()

    return {"message": "评价已提交，审核通过后将公开显示"}


@router.post("/{review_id}/helpful", summary="标记评价有用（公开）")
async def mark_helpful(
    review_id: int,
    db:        AsyncSession = Depends(get_db),
):
    r = await db.execute(select(ProductReview).where(ProductReview.id == review_id))
    review = r.scalar_one_or_none()
    if not review:
        raise HTTPException(status_code=404, detail="评价不存在")
    review.helpful_count += 1
    db.add(review)
    await db.commit()
    return {"helpful_count": review.helpful_count}
