"""Bilgi tabanı DB erişimi — source + chunk. Her sorgu tenant_id filtreli."""
from fastapi import Depends
from sqlalchemy import delete, select
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.models.knowledge import FlovyKnowledgeChunk, FlovyKnowledgeSource


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

    # --- Sources ---

    async def get_source(self, source_id: str, tenant_id: str) -> FlovyKnowledgeSource | None:
        result = await self.db.execute(
            select(FlovyKnowledgeSource).where(
                FlovyKnowledgeSource.id == source_id,
                FlovyKnowledgeSource.tenant_id == tenant_id,
            )
        )
        return result.scalar_one_or_none()

    async def find_product_source(
        self, tenant_id: str, product_id: str
    ) -> FlovyKnowledgeSource | None:
        result = await self.db.execute(
            select(FlovyKnowledgeSource).where(
                FlovyKnowledgeSource.tenant_id == tenant_id,
                FlovyKnowledgeSource.source_type == "product",
                FlovyKnowledgeSource.url == f"product:{product_id}",
            )
        )
        return result.scalar_one_or_none()

    async def list_sources(self, tenant_id: str) -> list[FlovyKnowledgeSource]:
        result = await self.db.execute(
            select(FlovyKnowledgeSource)
            .where(FlovyKnowledgeSource.tenant_id == tenant_id)
            .order_by(FlovyKnowledgeSource.created_at.desc())
        )
        return list(result.scalars().all())

    async def create_source(self, **kwargs) -> FlovyKnowledgeSource:
        source = FlovyKnowledgeSource(**kwargs)
        self.db.add(source)
        await self.db.commit()
        await self.db.refresh(source)
        return source

    async def update_source(
        self, source: FlovyKnowledgeSource, **kwargs
    ) -> FlovyKnowledgeSource:
        for key, value in kwargs.items():
            setattr(source, key, value)
        await self.db.commit()
        await self.db.refresh(source)
        return source

    async def delete_source(self, source: FlovyKnowledgeSource) -> None:
        await self.db.delete(source)  # chunk'lar cascade ile silinir
        await self.db.commit()

    # --- Chunks ---

    async def delete_chunks_of_source(self, source_id: str, tenant_id: str) -> None:
        await self.db.execute(
            delete(FlovyKnowledgeChunk).where(
                FlovyKnowledgeChunk.source_id == source_id,
                FlovyKnowledgeChunk.tenant_id == tenant_id,
            )
        )
        await self.db.commit()

    async def add_chunk(self, **kwargs) -> FlovyKnowledgeChunk:
        chunk = FlovyKnowledgeChunk(**kwargs)
        self.db.add(chunk)
        await self.db.commit()
        await self.db.refresh(chunk)
        return chunk

    async def list_chunks_for_search(
        self, tenant_id: str, source_type: str | None = None, limit: int = 2000
    ) -> list[FlovyKnowledgeChunk]:
        stmt = select(FlovyKnowledgeChunk).where(
            FlovyKnowledgeChunk.tenant_id == tenant_id,
            FlovyKnowledgeChunk.embedding.is_not(None),
        )
        if source_type:
            stmt = stmt.where(FlovyKnowledgeChunk.source_type == source_type)
        result = await self.db.execute(stmt.limit(limit))
        return list(result.scalars().all())
