from fastapi import FastAPI

from app.api.routes import router, set_container, ServiceContainer
from app.core.config import get_settings
from app.core.logging import configure_logging
from app.core.observability import MetricsMiddleware, metrics_response
from app.repositories.clickhouse_repository import ClickHouseRepository
from app.repositories.mysql_repository import MySQLRepository
from app.repositories.qdrant_repository import QdrantRepository
from app.repositories.redis_cache import RedisCacheRepository
from app.services.embedding_service import EmbeddingService
from app.services.ingestion_service import IngestionService
from app.services.llm_service import LLMService
from app.services.report_service import ReportService
from app.services.retrieval_service import RetrievalService
from app.services.reranker_service import RerankerService
from app.services.scoring_service import ScoringService

settings = get_settings()
configure_logging(settings.log_level)

app = FastAPI(title=settings.app_name)
app.add_middleware(MetricsMiddleware)

cache_repo = RedisCacheRepository(settings.redis_url)
qdrant_repo = QdrantRepository(
    host=settings.qdrant_host,
    port=settings.qdrant_port,
    collection_name=settings.qdrant_collection,
    https=settings.qdrant_https,
    api_key=settings.qdrant_api_key,
)
mysql_repo = MySQLRepository(
    host=settings.mysql_host,
    port=settings.mysql_port,
    user=settings.mysql_user,
    password=settings.mysql_password,
    db=settings.mysql_db,
)
clickhouse_repo = ClickHouseRepository(
    host=settings.clickhouse_host,
    port=settings.clickhouse_port,
    username=settings.clickhouse_user,
    password=settings.clickhouse_password,
    database=settings.clickhouse_db,
)

embedding_service = EmbeddingService(
    model_name=settings.embedding_model_name,
    device=settings.embedding_device,
    cache_repo=cache_repo,
    cache_ttl=settings.embedding_cache_ttl_seconds,
)
reranker_service = RerankerService(
    model_name=settings.reranker_model_name,
    device=settings.embedding_device,
)
llm_service = LLMService(
    base_url=settings.llm_base_url,
    api_key=settings.llm_api_key,
    model=settings.llm_model,
    timeout_seconds=settings.llm_timeout_seconds,
)

ingestion_service = IngestionService(qdrant_repo=qdrant_repo, mysql_repo=mysql_repo, emb_service=embedding_service)
retrieval_service = RetrievalService(
    qdrant_repo=qdrant_repo,
    emb_service=embedding_service,
    reranker_service=reranker_service,
    cache_repo=cache_repo,
    retrieval_cache_ttl=settings.retrieval_cache_ttl_seconds,
    candidate_k=settings.retrieval_candidate_k,
    default_top_k=settings.retrieval_top_k,
    keyword_weight=settings.hybrid_keyword_weight,
)
scoring_service = ScoringService(mysql_repo=mysql_repo, clickhouse_repo=clickhouse_repo, llm_service=llm_service)
report_service = ReportService(clickhouse_repo=clickhouse_repo)

container = ServiceContainer()
container.ingestion = ingestion_service
container.retrieval = retrieval_service
container.llm = llm_service
container.scoring = scoring_service
container.report = report_service
set_container(container)

app.include_router(router)


@app.get('/health')
def health():
    return {'status': 'ok'}


@app.get('/metrics')
def metrics():
    return metrics_response()
