"""
素材 CRUD
=========
"""

from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession

from app.crud.base import CRUDBase
from app.models.broll_material import BrollMaterial


class BrollMaterialCRUD(CRUDBase[BrollMaterial]):
    """素材数据访问"""

    def __init__(self) -> None:
        super().__init__(BrollMaterial)

    async def get_active_by_category_and_duration(
        self,
        db: AsyncSession,
        *,
        category_id: int,
        min_duration: float,
    ) -> list[BrollMaterial]:
        """
        获取指定分类下、时长大于等于要求、状态为 active 的素材列表
        """
        result = await db.execute(
            select(BrollMaterial).where(
                BrollMaterial.category_id == category_id,
                BrollMaterial.duration >= min_duration,
                BrollMaterial.status == "active",
            )
        )
        return list(result.scalars().all())

    async def get_active_by_categories(
        self, db: AsyncSession, *, category_ids: list[int]
    ) -> list[BrollMaterial]:
        """批量获取指定分类下状态为 active 的素材列表（不过滤时长）"""
        if not category_ids:
            return []
        result = await db.execute(
            select(BrollMaterial).where(
                BrollMaterial.category_id.in_(category_ids),
                BrollMaterial.status == "active",
            )
        )
        return list(result.scalars().all())

    async def increment_usage_count(
        self, db: AsyncSession, *, material_id: int
    ) -> None:
        """
        原子递增素材使用次数

        使用 UPDATE ... SET usage_count = usage_count + 1 避免读-改-写竞态。
        """
        await db.execute(
            update(BrollMaterial)
            .where(BrollMaterial.id == material_id)
            .values(usage_count=BrollMaterial.usage_count + 1)
        )

    async def increment_usage_count_batch(
        self, db: AsyncSession, *, material_ids: list[int]
    ) -> None:
        """批量原子递增素材使用次数"""
        if not material_ids:
            return
        await db.execute(
            update(BrollMaterial)
            .where(BrollMaterial.id.in_(material_ids))
            .values(usage_count=BrollMaterial.usage_count + 1)
        )


# 导出实例
broll_material = BrollMaterialCRUD()
