from app.services.audit import log_audit
"""品牌管理与前台品牌接口"""
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query, Request, status
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_admin_user, get_db
from app.core.models.brand import Brand
from app.core.models.user import User
from app.core.services.tenant import resolve_public_tenant_id
from app.schemas.common import PageResult
from app.schemas.product import BrandCreate, BrandOut, BrandUpdate

router = APIRouter(prefix="/brands", tags=["品牌管理"])
store_router = APIRouter(prefix="/store/brands", tags=["前台品牌"])


@router.get("", response_model=PageResult[BrandOut], summary="品牌列表")
async def list_brands(
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    keyword: Optional[str] = None,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    q = select(Brand).where(Brand.tenant_id == admin.tenant_id)
    if keyword:
        kw = f"%{keyword.strip().lower()}%"
        q = q.where(func.lower(Brand.name).like(kw))

    total = (await db.execute(select(func.count()).select_from(q.subquery()))).scalar() or 0
    result = await db.execute(
        q.order_by(Brand.sort_order.asc(), Brand.id.desc())
        .offset((page - 1) * page_size)
        .limit(page_size)
    )
    return PageResult(items=result.scalars().all(), total=total, page=page, page_size=page_size)


@router.post("", response_model=BrandOut, status_code=status.HTTP_201_CREATED, summary="创建品牌")
async def create_brand(
    body: BrandCreate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    dup = await db.execute(
        select(Brand).where(Brand.tenant_id == admin.tenant_id, Brand.slug == body.slug)
    )
    if dup.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="该品牌 slug 已存在")

    brand = Brand(tenant_id=admin.tenant_id, **body.model_dump())
    brand.is_active = 1 if body.is_active else 0
    brand.is_featured = 1 if body.is_featured else 0
    db.add(brand)
    await db.commit()
    await db.refresh(brand)

    await log_audit(
        db=db,
        tenant_id=admin.tenant_id,
        action="brands.create",
        actor_type="admin",
        actor_id=admin.id,
        actor_name=getattr(admin, "name", None),
        target_type="brands",
        target_id=brand.id,
        target_name=brand.name,
    )
    return brand


@router.get("/{brand_id}", response_model=BrandOut, summary="品牌详情")
async def get_brand(
    brand_id: int,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(Brand).where(Brand.id == brand_id, Brand.tenant_id == admin.tenant_id)
    )
    brand = result.scalar_one_or_none()
    if not brand:
        raise HTTPException(status_code=404, detail="品牌不存在")
    return brand


@router.put("/{brand_id}", response_model=BrandOut, summary="更新品牌")
async def update_brand(
    brand_id: int,
    body: BrandUpdate,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(Brand).where(Brand.id == brand_id, Brand.tenant_id == admin.tenant_id)
    )
    brand = result.scalar_one_or_none()
    if not brand:
        raise HTTPException(status_code=404, detail="品牌不存在")

    data = body.model_dump(exclude_unset=True)
    if "slug" in data:
        dup = await db.execute(
            select(Brand).where(
                Brand.tenant_id == admin.tenant_id,
                Brand.slug == data["slug"],
                Brand.id != brand_id,
            )
        )
        if dup.scalar_one_or_none():
            raise HTTPException(status_code=400, detail="该品牌 slug 已存在")

    for key, value in data.items():
        if key in ("is_active", "is_featured"):
            value = 1 if value else 0
        setattr(brand, key, value)

    await db.commit()
    await db.refresh(brand)

    await log_audit(
        db=db,
        tenant_id=admin.tenant_id,
        action="brands.update",
        actor_type="admin",
        actor_id=admin.id,
        actor_name=getattr(admin, "name", None),
        target_type="brands",
        target_id=brand_id,
        target_name=brand.name,
    )
    return brand


@router.delete("/{brand_id}", status_code=status.HTTP_204_NO_CONTENT, summary="删除品牌")
async def delete_brand(
    brand_id: int,
    db: AsyncSession = Depends(get_db),
    admin: User = Depends(get_admin_user),
):
    result = await db.execute(
        select(Brand).where(Brand.id == brand_id, Brand.tenant_id == admin.tenant_id)
    )
    brand = result.scalar_one_or_none()
    if not brand:
        raise HTTPException(status_code=404, detail="品牌不存在")
    brand_name = brand.name
    await db.delete(brand)
    await db.commit()

    await log_audit(
        db=db,
        tenant_id=admin.tenant_id,
        action="brands.delete",
        actor_type="admin",
        actor_id=admin.id,
        actor_name=getattr(admin, "name", None),
        target_type="brands",
        target_id=brand_id,
        target_name=brand_name,
    )


@store_router.get("", response_model=list[BrandOut], summary="前台品牌列表")
async def store_list_brands(
    request: Request,
    tenant_id: Optional[int] = Query(None),
    db: AsyncSession = Depends(get_db),
):
    tid = await resolve_public_tenant_id(db, tenant_id=tenant_id, request=request)
    result = await db.execute(
        select(Brand)
        .where(Brand.tenant_id == tid, Brand.is_active == 1)
        .order_by(Brand.is_featured.desc(), Brand.sort_order.asc(), Brand.name.asc())
    )
    return result.scalars().all()


@store_router.get("/{slug}", response_model=BrandOut, summary="前台品牌详情")
async def store_get_brand(
    slug: str,
    request: Request,
    tenant_id: Optional[int] = Query(None),
    db: AsyncSession = Depends(get_db),
):
    tid = await resolve_public_tenant_id(db, tenant_id=tenant_id, request=request)
    result = await db.execute(
        select(Brand).where(Brand.tenant_id == tid, Brand.slug == slug, Brand.is_active == 1)
    )
    brand = result.scalar_one_or_none()
    if not brand:
        raise HTTPException(status_code=404, detail="品牌不存在")
    return brand
