from collections.abc import AsyncGenerator

from fastapi import Depends, Request
from sqlalchemy.ext.asyncio import AsyncSession

from vmk_data_collector.core.config import settings
from vmk_data_collector.db.repositories.ai_enrichment import (
    AiEnrichmentRepository,
)
from vmk_data_collector.db.repositories.custom_field import (
    CustomFieldRepository,
)
from vmk_data_collector.db.repositories.data_source import (
    DataSourceRepository,
)
from vmk_data_collector.db.repositories.image import ImageRepository
from vmk_data_collector.db.repositories.property import PropertyRepository
from vmk_data_collector.db.repositories.property_type import (
    PropertyTypeRepository,
)
from vmk_data_collector.db.repositories.raw_data import RawDataRepository
from vmk_data_collector.db.repositories.snapshot import SnapshotRepository
from vmk_data_collector.db.session import AsyncSessionLocal
from vmk_data_collector.services.ai_enricher import AiEnricher
from vmk_data_collector.services.ai_image_analyzer import AiImageAnalyzer
from vmk_data_collector.services.ai_normalizer import AiNormalizer
from vmk_data_collector.services.image_downloader import ImageDownloader
from vmk_data_collector.services.ollama_client import OllamaClient
from vmk_data_collector.services.property_pipeline import PropertyPipeline


async def get_db() -> AsyncGenerator[AsyncSession, None]:
    async with AsyncSessionLocal() as session:
        yield session


def get_ollama_client(request: Request) -> OllamaClient:
    return request.app.state.ollama_client


async def get_property_pipeline(
    request: Request,
    db: AsyncSession = Depends(get_db),
    client: OllamaClient = Depends(get_ollama_client),
) -> PropertyPipeline:
    normalizer = AiNormalizer(client=client)
    image_analyzer = AiImageAnalyzer(client=client)
    enricher = AiEnricher(client=client)
    downloader = ImageDownloader(
        storage_path=settings.image_storage_path_abs
    )

    return PropertyPipeline(
        raw_repo=RawDataRepository(db),
        property_repo=PropertyRepository(db),
        image_repo=ImageRepository(db),
        custom_field_repo=CustomFieldRepository(db),
        snapshot_repo=SnapshotRepository(db),
        enrichment_repo=AiEnrichmentRepository(db),
        data_source_repo=DataSourceRepository(db),
        property_type_repo=PropertyTypeRepository(db),
        normalizer=normalizer,
        image_downloader=downloader,
        image_analyzer=image_analyzer,
        enricher=enricher,
        active_jobs=getattr(request.app.state, "active_jobs", None),
    )
