"""Embedding indexleme Celery task'ları. HTTP request içinde DEĞİL (ARCHITECTURE §8).

Rate limit 10/m — Gemini text-embedding-004 free tier 15/m sınırı için.
"""
import asyncio
import logging

from sqlalchemy import select

from app.database import AsyncSessionFactory
from app.models.product import Product
from app.repositories.knowledge_repo import KnowledgeRepository
from app.services.rag.embedding_client import get_embedding_client
from app.services.rag.knowledge_indexer import KnowledgeIndexer
from app.tasks.celery_app import celery_app

logger = logging.getLogger("flovy")


async def _index_source(source_id: str, tenant_id: str) -> int:
    async with AsyncSessionFactory() as db:
        repo = KnowledgeRepository(db)
        indexer = KnowledgeIndexer(repo, get_embedding_client())
        source = await repo.get_source(source_id, tenant_id)
        if source is None:
            logger.warning("index_knowledge: source bulunamadı %s", source_id)
            return 0
        return await indexer.reindex_source(source)


async def _index_product(product_id: str, tenant_id: str) -> int:
    async with AsyncSessionFactory() as db:
        repo = KnowledgeRepository(db)
        indexer = KnowledgeIndexer(repo, get_embedding_client())
        result = await db.execute(
            select(Product).where(
                Product.id == product_id, Product.tenant_id == tenant_id
            )
        )
        product = result.scalar_one_or_none()
        if product is None:
            logger.warning("index_product: ürün bulunamadı %s", product_id)
            return 0
        return await indexer.index_product(product)


async def _remove_product_index(product_id: str, tenant_id: str) -> None:
    async with AsyncSessionFactory() as db:
        repo = KnowledgeRepository(db)
        source = await repo.find_product_source(tenant_id, product_id)
        if source is not None:
            await repo.delete_source(source)  # chunk'lar cascade ile silinir


@celery_app.task(name="index_knowledge", rate_limit="10/m")
def index_knowledge(source_id: str, tenant_id: str) -> int:
    return asyncio.run(_index_source(source_id, tenant_id))


@celery_app.task(name="remove_product_index")
def remove_product_index(product_id: str, tenant_id: str) -> None:
    asyncio.run(_remove_product_index(product_id, tenant_id))


@celery_app.task(name="index_product", rate_limit="10/m")
def index_product(product_id: str, tenant_id: str) -> int:
    return asyncio.run(_index_product(product_id, tenant_id))
