from __future__ import annotations

from mcp.server.fastmcp import FastMCP

from ..config import DEFAULT_PROFILE
from ..errors import QingflowApiError, raise_tool_error
from ..json_types import JSONObject
from .base import ToolBase


class PortalTools(ToolBase):
    def register(self, mcp: FastMCP) -> None:
        @mcp.tool()
        def portal_list(profile: str = DEFAULT_PROFILE) -> JSONObject:
            return self.portal_list(profile=profile)

        @mcp.tool()
        def portal_get(profile: str = DEFAULT_PROFILE, dash_key: str = "", being_draft: bool = False) -> JSONObject:
            return self.portal_get(profile=profile, dash_key=dash_key, being_draft=being_draft)

        @mcp.tool()
        def portal_create(profile: str = DEFAULT_PROFILE, payload: JSONObject | None = None) -> JSONObject:
            return self.portal_create(profile=profile, payload=payload or {})

        @mcp.tool(description=self._high_risk_tool_description(operation="update", target="portal configuration"))
        def portal_update(profile: str = DEFAULT_PROFILE, dash_key: str = "", payload: JSONObject | None = None) -> JSONObject:
            return self.portal_update(profile=profile, dash_key=dash_key, payload=payload or {})

        @mcp.tool(description=self._high_risk_tool_description(operation="delete", target="portal configuration"))
        def portal_delete(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> JSONObject:
            return self.portal_delete(profile=profile, dash_key=dash_key)

        @mcp.tool()
        def portal_publish(profile: str = DEFAULT_PROFILE, dash_key: str = "") -> JSONObject:
            return self.portal_publish(profile=profile, dash_key=dash_key)

    def portal_list(self, *, profile: str) -> JSONObject:
        def runner(session_profile, context):
            result = self.backend.request("GET", context, "/dash")
            return {"profile": profile, "ws_id": session_profile.selected_ws_id, "items": result}

        return self._run(profile, runner)

    def portal_get(self, *, profile: str, dash_key: str, being_draft: bool = False) -> JSONObject:
        self._require_dash_key(dash_key)

        def runner(session_profile, context):
            result = self.backend.request("GET", context, f"/dash/{dash_key}", params={"beingDraft": being_draft})
            return {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result}

        return self._run(profile, runner)

    def portal_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
        body = self._require_dict(payload)

        def runner(session_profile, context):
            result = self.backend.request("POST", context, "/dash", json_body=body)
            return {"profile": profile, "ws_id": session_profile.selected_ws_id, "result": result}

        return self._run(profile, runner)

    def portal_update(self, *, profile: str, dash_key: str, payload: JSONObject) -> JSONObject:
        self._require_dash_key(dash_key)
        body = self._require_dict(payload)

        def runner(session_profile, context):
            result = self.backend.request("POST", context, f"/dash/{dash_key}", json_body=body)
            return self._attach_human_review_notice(
                {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result},
                operation="update",
                target="portal configuration",
            )

        return self._run(profile, runner)

    def portal_delete(self, *, profile: str, dash_key: str) -> JSONObject:
        self._require_dash_key(dash_key)

        def runner(session_profile, context):
            result = self.backend.request("DELETE", context, f"/dash/{dash_key}")
            return self._attach_human_review_notice(
                {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result},
                operation="delete",
                target="portal configuration",
            )

        return self._run(profile, runner)

    def portal_publish(self, *, profile: str, dash_key: str) -> JSONObject:
        self._require_dash_key(dash_key)

        def runner(session_profile, context):
            result = self.backend.request("POST", context, f"/dash/{dash_key}/publish")
            return {"profile": profile, "ws_id": session_profile.selected_ws_id, "dash_key": dash_key, "result": result}

        return self._run(profile, runner)

    def _require_dash_key(self, dash_key: str) -> None:
        if not dash_key:
            raise_tool_error(QingflowApiError.config_error("dash_key is required"))
