from collections.abc import AsyncGenerator

from fastapi import Depends
from sqlalchemy.ext.asyncio import AsyncSession

from app.application.services.auth_service import AuthService
from app.application.services.ai_agent_service import AiAgentService
from app.application.services.chart_of_account_service import ChartOfAccountService
from app.application.services.company_service import CompanyService
from app.application.services.inventory_service import InventoryService
from app.application.services.purchase_service import PurchaseService
from app.application.services.report_service import ReportService
from app.application.services.sales_service import SalesService
from app.application.services.settings_service import SettingsService
from app.application.services.users_roles_service import UsersRolesService
from app.application.services.voucher_service import VoucherService
from app.core.database import get_session
from app.infrastructure.repositories.chart_of_account_mysql_repository import MySQLChartOfAccountRepository
from app.infrastructure.repositories.company_mysql_repository import MySQLCompanyRepository
from app.infrastructure.repositories.inventory_mysql_repository import MySQLInventoryRepository
from app.infrastructure.repositories.purchase_mysql_repository import MySQLPurchaseRepository
from app.infrastructure.repositories.refresh_token_mysql_repository import MySQLRefreshTokenRepository
from app.infrastructure.repositories.report_mysql_repository import MySQLReportRepository
from app.infrastructure.repositories.sales_mysql_repository import MySQLSalesRepository
from app.infrastructure.repositories.settings_mysql_repository import MySQLSettingsRepository
from app.infrastructure.repositories.user_registration_mysql_repository import MySQLUserRegistrationRepository
from app.infrastructure.repositories.users_roles_mysql_repository import MySQLUsersRolesRepository
from app.infrastructure.repositories.voucher_mysql_repository import MySQLVoucherRepository


async def get_db_session() -> AsyncGenerator[AsyncSession, None]:
    async for session in get_session():
        yield session


async def get_auth_service(session: AsyncSession = Depends(get_db_session)) -> AuthService:
    return AuthService(
        MySQLUserRegistrationRepository(session),
        MySQLRefreshTokenRepository(session),
        MySQLUsersRolesRepository(session),
    )


async def get_chart_of_account_service(
    session: AsyncSession = Depends(get_db_session),
) -> ChartOfAccountService:
    return ChartOfAccountService(
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
    )


async def get_company_service(session: AsyncSession = Depends(get_db_session)) -> CompanyService:
    return CompanyService(MySQLCompanyRepository(session))


async def get_voucher_service(session: AsyncSession = Depends(get_db_session)) -> VoucherService:
    return VoucherService(
        MySQLVoucherRepository(session),
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
    )


async def get_report_service(session: AsyncSession = Depends(get_db_session)) -> ReportService:
    return ReportService(
        MySQLChartOfAccountRepository(session),
        MySQLVoucherRepository(session),
        MySQLReportRepository(session),
        MySQLCompanyRepository(session),
    )


async def get_inventory_service(
    session: AsyncSession = Depends(get_db_session),
) -> InventoryService:
    return InventoryService(
        MySQLInventoryRepository(session),
        MySQLCompanyRepository(session),
    )


async def get_purchase_service(
    session: AsyncSession = Depends(get_db_session),
) -> PurchaseService:
    voucher_service = VoucherService(
        MySQLVoucherRepository(session),
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
    )
    return PurchaseService(
        MySQLPurchaseRepository(session),
        MySQLInventoryRepository(session),
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
        voucher_service,
    )


async def get_sales_service(
    session: AsyncSession = Depends(get_db_session),
) -> SalesService:
    voucher_service = VoucherService(
        MySQLVoucherRepository(session),
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
    )
    return SalesService(
        MySQLSalesRepository(session),
        MySQLInventoryRepository(session),
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
        voucher_service,
    )


async def get_users_roles_service(
    session: AsyncSession = Depends(get_db_session),
) -> UsersRolesService:
    return UsersRolesService(
        MySQLUsersRolesRepository(session),
        MySQLCompanyRepository(session),
        MySQLInventoryRepository(session),
    )


async def get_settings_service(
    session: AsyncSession = Depends(get_db_session),
) -> SettingsService:
    return SettingsService(
        MySQLSettingsRepository(session),
        MySQLCompanyRepository(session),
    )


async def get_ai_agent_service(
    session: AsyncSession = Depends(get_db_session),
) -> AiAgentService:
    inventory = InventoryService(
        MySQLInventoryRepository(session),
        MySQLCompanyRepository(session),
    )
    voucher_service = VoucherService(
        MySQLVoucherRepository(session),
        MySQLChartOfAccountRepository(session),
        MySQLCompanyRepository(session),
    )
    return AiAgentService(
        inventory,
        PurchaseService(
            MySQLPurchaseRepository(session),
            MySQLInventoryRepository(session),
            MySQLChartOfAccountRepository(session),
            MySQLCompanyRepository(session),
            voucher_service,
        ),
        SalesService(
            MySQLSalesRepository(session),
            MySQLInventoryRepository(session),
            MySQLChartOfAccountRepository(session),
            MySQLCompanyRepository(session),
            voucher_service,
        ),
        voucher_service,
        ChartOfAccountService(
            MySQLChartOfAccountRepository(session),
            MySQLCompanyRepository(session),
        ),
        UsersRolesService(
            MySQLUsersRolesRepository(session),
            MySQLCompanyRepository(session),
            MySQLInventoryRepository(session),
        ),
        ReportService(
            MySQLChartOfAccountRepository(session),
            MySQLVoucherRepository(session),
            MySQLReportRepository(session),
            MySQLCompanyRepository(session),
        ),
    )
