from typing import Callable

from .route import auto_generate_route


class AppDefinition:
    """
    Use this class to create Compose Apps.

    @param `name`: The name of the app. Used to identify the app in the UI, and as the title of the browser tab. For example: "User Management App".


    @param `handler`: The handler function for the app.


    @param `route`: A unique route to assign to the app. If given, the route will be used as the URL slug when using the app. If not, the route will be auto-generated based on the app name.

    The route should not start with a forward slash '/'. Just type the route name.

    Correct usage: "user-management-app"
    Incorrect usage: "/user-management-app" or "users/management-app"


    @param `description`: A short description of the app to display on the home page.


    @param `hidden`: Whether the app should be hidden from the home page.
    """

    def __init__(
        self,
        name: str,
        handler: Callable,
        *,
        route: str | None = None,
        description: str | None = None,
        hidden: bool = False
    ):
        if not name:
            raise ValueError("Missing 'name' field in Compose.App constructor")

        if not handler:
            raise ValueError("Missing 'handler' field in Compose.App constructor")

        self.name = name
        self.handler = handler
        self.description = description
        self.hidden = hidden

        self._isAutoGeneratedRoute = route == None

        self._route = auto_generate_route(name) if self._isAutoGeneratedRoute else route

        if self._route and self._route.startswith("/"):
            raise ValueError(
                "Route should not start with a forward slash '/'. Just type the route name (e.g. 'my-app')."
            )

    @property
    def route(self) -> str:
        return self._route

    @property
    def is_auto_generated_route(self) -> bool:
        return self._isAutoGeneratedRoute

    def set_route(self, route: str, isAutoGenerated: bool) -> None:
        self._route = route
        self._isAutoGeneratedRoute = isAutoGenerated

    def summarize(self) -> str:
        return {
            "name": self.name,
            "route": self.route,
            "description": self.description,
            "hidden": self.hidden,
        }
