"""FastAPI dependency injection functions and View base class.

Provides injectable dependencies for accessing core, config, render, and other
shared resources in route handlers.
"""

from typing import Any, cast

from fastapi import Depends, Request
from jinja2 import Environment
from mm_telegram import PrivateBot
from starlette.datastructures import FormData

from mm_base6.config import Config
from mm_base6.core.builtin_services.settings import BaseSettings
from mm_base6.core.builtin_services.state import BaseState
from mm_base6.core.core import CoreProtocol
from mm_base6.core.db import BaseDb
from mm_base6.server.jinja import Render


async def get_core[SC: BaseSettings, ST: BaseState, DB: BaseDb, SR](
    request: Request,
) -> CoreProtocol[SC, ST, DB, SR]:
    """Extract the application core from request state."""
    return cast(CoreProtocol[SC, ST, DB, SR], request.app.state.core)


async def get_render(request: Request) -> Render:
    """Create a Render instance with Jinja environment from request state."""
    jinja_env = cast(Environment, request.app.state.jinja_env)
    return Render(jinja_env, request)


async def get_config(request: Request) -> Config:
    """Extract the application config from request state."""
    return cast(Config, request.app.state.core.config)


async def get_form_data(request: Request) -> FormData:
    """Parse and return form data from the request."""
    return await request.form()


async def get_telegram_bot(request: Request) -> PrivateBot:
    """Extract the Telegram bot instance from request state."""
    return cast(PrivateBot, request.app.state.telegram_bot)


class View[SC: BaseSettings, ST: BaseState, DB: BaseDb, SR]:
    """Base class for CBV routes with auto-injected dependencies.

    Provides access to core, telegram_bot, config, form_data, and render via FastAPI
    dependency injection. Subclass and use with @cbv decorator.
    """

    core: CoreProtocol[SC, ST, DB, SR] = Depends(get_core)
    telegram_bot: PrivateBot = Depends(get_telegram_bot)
    config: Config = Depends(get_config)
    form_data: FormData = Depends(get_form_data)
    render: Render = Depends(get_render)


# Type alias for internal library routers
InternalView = View[BaseSettings, BaseState, BaseDb, Any]
