"""
Dependency Injection for Distribution Service
"""

from typing import AsyncGenerator
from fastapi import Depends
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.database import get_db
from app.core.config import settings
from app.repositories.delivery_route_repository import DeliveryRouteRepository
from app.repositories.shipment_repository import ShipmentRepository
from app.repositories.delivery_schedule_repository import DeliveryScheduleRepository
from app.services.distribution_service import DistributionService
from app.services.routing_optimizer import RoutingOptimizer
from shared.clients.tenant_client import TenantServiceClient
from shared.clients.inventory_client import InventoryServiceClient
from shared.clients.procurement_client import ProcurementServiceClient



async def get_db_session() -> AsyncGenerator[AsyncSession, None]:
    """Get database session dependency"""
    async for session in get_db():
        yield session


async def get_route_repository(db_session: AsyncSession = Depends(get_db_session)) -> DeliveryRouteRepository:
    """Get delivery route repository dependency"""
    return DeliveryRouteRepository(db_session)


async def get_shipment_repository(db_session: AsyncSession = Depends(get_db_session)) -> ShipmentRepository:
    """Get shipment repository dependency"""
    return ShipmentRepository(db_session)


async def get_delivery_schedule_repository(db_session: AsyncSession = Depends(get_db_session)) -> DeliveryScheduleRepository:
    """Get delivery schedule repository dependency"""
    return DeliveryScheduleRepository(db_session)


def get_tenant_client() -> TenantServiceClient:
    """Get tenant service client dependency"""
    return TenantServiceClient(settings)


def get_inventory_client() -> InventoryServiceClient:
    """Get inventory service client dependency"""
    return InventoryServiceClient(settings)


def get_procurement_client() -> ProcurementServiceClient:
    """Get procurement service client dependency"""
    return ProcurementServiceClient(settings)


def get_routing_optimizer() -> RoutingOptimizer:
    """Get routing optimizer service dependency"""
    return RoutingOptimizer()


def get_distribution_service(
    route_repository: DeliveryRouteRepository = Depends(get_route_repository),
    shipment_repository: ShipmentRepository = Depends(get_shipment_repository),
    schedule_repository: DeliveryScheduleRepository = Depends(get_delivery_schedule_repository),
    tenant_client: TenantServiceClient = Depends(get_tenant_client),
    inventory_client: InventoryServiceClient = Depends(get_inventory_client),
    procurement_client: ProcurementServiceClient = Depends(get_procurement_client),
    routing_optimizer: RoutingOptimizer = Depends(get_routing_optimizer)
) -> DistributionService:
    """Get distribution service dependency with all required clients"""
    return DistributionService(
        route_repository=route_repository,
        shipment_repository=shipment_repository,
        schedule_repository=schedule_repository,
        tenant_client=tenant_client,
        inventory_client=inventory_client,
        procurement_client=procurement_client,
        routing_optimizer=routing_optimizer
    )