"""Ürün + varyant DB erişimi. Her sorgu tenant_id filtreli, deleted_at IS NULL."""
from datetime import UTC, datetime
from decimal import Decimal

from fastapi import Depends
from sqlalchemy import and_, or_, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.models.product import Product, ProductVariant


class ProductRepository:
    def __init__(self, db: AsyncSession = Depends(get_db)):
        self.db = db

    async def get(self, product_id: str, tenant_id: str) -> Product | None:
        result = await self.db.execute(
            select(Product).where(
                Product.id == product_id,
                Product.tenant_id == tenant_id,
                Product.deleted_at.is_(None),
            )
        )
        return result.scalar_one_or_none()

    async def list_by_tenant(
        self,
        tenant_id: str,
        limit: int,
        cursor_created_at: datetime | None = None,
        cursor_id: str | None = None,
    ) -> list[Product]:
        """Keyset pagination — (created_at, id) DESC."""
        stmt = select(Product).where(
            Product.tenant_id == tenant_id,
            Product.deleted_at.is_(None),
        )
        if cursor_created_at is not None and cursor_id is not None:
            stmt = stmt.where(
                or_(
                    Product.created_at < cursor_created_at,
                    and_(
                        Product.created_at == cursor_created_at,
                        Product.id < cursor_id,
                    ),
                )
            )
        stmt = stmt.order_by(Product.created_at.desc(), Product.id.desc()).limit(limit)
        result = await self.db.execute(stmt)
        return list(result.scalars().all())

    async def search(
        self,
        tenant_id: str,
        query: str | None = None,
        category_id: str | None = None,
        max_price: Decimal | None = None,
        limit: int = 10,
    ) -> list[Product]:
        stmt = select(Product).where(
            Product.tenant_id == tenant_id,
            Product.deleted_at.is_(None),
            Product.is_active.is_(True),
        )
        if query:
            like = f"%{query}%"
            stmt = stmt.where(
                or_(Product.title.ilike(like), Product.description.ilike(like))
            )
        if category_id:
            stmt = stmt.where(Product.category_id == category_id)
        if max_price is not None:
            stmt = stmt.where(Product.price <= max_price)
        stmt = stmt.order_by(Product.created_at.desc()).limit(limit)
        result = await self.db.execute(stmt)
        return list(result.scalars().all())

    async def create(self, **kwargs) -> Product:
        product = Product(**kwargs)
        self.db.add(product)
        await self.db.commit()
        await self.db.refresh(product)
        return product

    async def update(self, product: Product, **kwargs) -> Product:
        for key, value in kwargs.items():
            setattr(product, key, value)
        await self.db.commit()
        await self.db.refresh(product)
        return product

    async def soft_delete(self, product: Product) -> None:
        product.deleted_at = datetime.now(UTC).replace(tzinfo=None)
        await self.db.commit()

    async def replace_variants(
        self, product: Product, variants: list[dict]
    ) -> Product:
        for existing in list(product.variants):
            await self.db.delete(existing)
        for v in variants:
            self.db.add(ProductVariant(product_id=product.id, **v))
        await self.db.commit()
        await self.db.refresh(product)
        return product
