from contextlib import asynccontextmanager
from pathlib import Path
from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.exceptions import ToolError
from quidclaw.config import QuidClawConfig
from quidclaw.core.ledger import Ledger

NOT_ACTIVE_MSG = (
    "QuidClaw is not active. Please call set_data_dir with the user's "
    "financial directory path first. The directory should contain a ledger/ "
    "folder, or be an empty directory to initialize a new one."
)


class AppContext:
    def __init__(self):
        self._config: QuidClawConfig = QuidClawConfig()
        self._ledger: Ledger | None = None

    @property
    def is_active(self) -> bool:
        """Whether QuidClaw is pointed at a data directory."""
        return self._config.is_configured and self._ledger is not None

    @property
    def config(self) -> QuidClawConfig:
        """Get config. Raises ToolError if not active."""
        if not self._config.is_configured:
            raise ToolError(NOT_ACTIVE_MSG)
        return self._config

    @property
    def ledger(self) -> Ledger:
        """Get ledger. Raises ToolError if not active."""
        if self._ledger is None:
            raise ToolError(NOT_ACTIVE_MSG)
        return self._ledger

    def activate(self, data_dir: str | Path) -> None:
        """Set the data directory and initialize the ledger."""
        self._config = QuidClawConfig(data_dir=Path(data_dir))
        self._ledger = Ledger(self._config)
        self._ledger.init()

    def detect(self, directory: str | Path) -> bool:
        """Check if a directory is a QuidClaw financial directory (has ledger/)."""
        return (Path(directory) / "ledger").is_dir()


@asynccontextmanager
async def app_lifespan(server: FastMCP):
    app = AppContext()
    # If QUIDCLAW_DATA_DIR is set, activate immediately
    if app._config.is_configured:
        app._ledger = Ledger(app._config)
        app._ledger.init()
    yield app


def create_server() -> FastMCP:
    mcp = FastMCP(
        "QuidClaw",
        instructions="Personal finance AI Agent powered by Beancount",
        lifespan=app_lifespan,
    )

    from quidclaw.mcp_server.tools import register_tools
    from quidclaw.mcp_server.prompts import register_prompts
    from quidclaw.mcp_server.resources import register_resources

    register_tools(mcp)
    register_prompts(mcp)
    register_resources(mcp)

    return mcp
