from __future__ import annotations

from mcp.server.fastmcp import FastMCP

from .backend_client import BackendClient
from .config import DEFAULT_PROFILE
from .session_store import SessionStore
from .tools.approval_tools import ApprovalTools
from .tools.auth_tools import AuthTools
from .tools.directory_tools import DirectoryTools
from .tools.file_tools import FileTools
from .tools.record_tools import RecordTools
from .tools.task_tools import TaskTools
from .tools.workspace_tools import WorkspaceTools


def build_user_server() -> FastMCP:
    server = FastMCP(
        "Qingflow App User MCP",
        instructions=(
            "Use this server for Qingflow record queries, record writes, task center operations, "
            "directory lookups, and approval actions. Avoid builder-side app or schema changes here."
        ),
    )
    sessions = SessionStore()
    backend = BackendClient()
    auth = AuthTools(sessions, backend)
    workspace = WorkspaceTools(sessions, backend)
    files = FileTools(sessions, backend)
    approvals = ApprovalTools(sessions, backend)
    tasks = TaskTools(sessions, backend)

    @server.tool()
    def auth_login(
        profile: str = DEFAULT_PROFILE,
        base_url: str | None = None,
        qf_version: str | None = None,
        email: str = "",
        password: str = "",
        persist: bool = True,
    ) -> dict:
        return auth.auth_login(
            profile=profile,
            base_url=base_url,
            qf_version=qf_version,
            email=email,
            password=password,
            persist=persist,
        )

    @server.tool()
    def auth_use_token(
        profile: str = DEFAULT_PROFILE,
        base_url: str | None = None,
        qf_version: str | None = None,
        token: str = "",
        ws_id: int | None = None,
        persist: bool = False,
    ) -> dict:
        return auth.auth_use_token(
            profile=profile,
            base_url=base_url,
            qf_version=qf_version,
            token=token,
            ws_id=ws_id,
            persist=persist,
        )

    @server.tool()
    def auth_whoami(profile: str = DEFAULT_PROFILE) -> dict:
        return auth.auth_whoami(profile=profile)

    @server.tool()
    def auth_logout(profile: str = DEFAULT_PROFILE, forget_persisted: bool = False) -> dict:
        return auth.auth_logout(profile=profile, forget_persisted=forget_persisted)

    @server.tool()
    def workspace_list(
        profile: str = DEFAULT_PROFILE,
        page_num: int = 1,
        page_size: int = 20,
        include_external: bool = False,
    ) -> dict:
        return workspace.workspace_list(
            profile=profile,
            page_num=page_num,
            page_size=page_size,
            include_external=include_external,
        )

    @server.tool()
    def workspace_select(profile: str = DEFAULT_PROFILE, ws_id: int = 0) -> dict:
        return workspace.workspace_select(profile=profile, ws_id=ws_id)

    @server.tool()
    def file_get_upload_info(
        profile: str = DEFAULT_PROFILE,
        upload_kind: str = "attachment",
        file_name: str = "",
        file_size: int = 0,
        upload_mark: str | None = None,
        content_type: str | None = None,
        bucket_type: str | None = None,
        path_id: int | None = None,
        file_related_url: str | None = None,
    ) -> dict:
        return files.file_get_upload_info(
            profile=profile,
            upload_kind=upload_kind,
            file_name=file_name,
            file_size=file_size,
            upload_mark=upload_mark,
            content_type=content_type,
            bucket_type=bucket_type,
            path_id=path_id,
            file_related_url=file_related_url,
        )

    @server.tool()
    def file_upload_local(
        profile: str = DEFAULT_PROFILE,
        upload_kind: str = "attachment",
        file_path: str = "",
        upload_mark: str | None = None,
        content_type: str | None = None,
        bucket_type: str | None = None,
        path_id: int | None = None,
        file_related_url: str | None = None,
    ) -> dict:
        return files.file_upload_local(
            profile=profile,
            upload_kind=upload_kind,
            file_path=file_path,
            upload_mark=upload_mark,
            content_type=content_type,
            bucket_type=bucket_type,
            path_id=path_id,
            file_related_url=file_related_url,
        )

    RecordTools(sessions, backend).register(server)
    DirectoryTools(sessions, backend).register(server)

    @server.tool()
    def record_comment_add(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        payload: dict | None = None,
    ) -> dict:
        return approvals.record_comment_add(profile=profile, app_key=app_key, apply_id=apply_id, payload=payload or {})

    @server.tool()
    def record_comment_list(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        page_size: int = 20,
        list_type: int | None = None,
        page_num: int | None = 1,
    ) -> dict:
        return approvals.record_comment_list(
            profile=profile,
            app_key=app_key,
            apply_id=apply_id,
            page_size=page_size,
            list_type=list_type,
            page_num=page_num,
        )

    @server.tool()
    def record_comment_mention_candidates(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        page_size: int = 20,
        page_num: int = 1,
        list_type: int | None = None,
        keyword: str | None = None,
    ) -> dict:
        return approvals.record_comment_mention_candidates(
            profile=profile,
            app_key=app_key,
            apply_id=apply_id,
            page_size=page_size,
            page_num=page_num,
            list_type=list_type,
            keyword=keyword,
        )

    @server.tool()
    def record_comment_mark_read(profile: str = DEFAULT_PROFILE, app_key: str = "", apply_id: int = 0) -> dict:
        return approvals.record_comment_mark_read(profile=profile, app_key=app_key, apply_id=apply_id)

    @server.tool()
    def record_comment_stats(profile: str = DEFAULT_PROFILE, app_key: str = "", apply_id: int = 0) -> dict:
        return approvals.record_comment_stats(profile=profile, app_key=app_key, apply_id=apply_id)

    @server.tool()
    def task_list(
        profile: str = DEFAULT_PROFILE,
        type: int = 1,
        process_status: int = 1,
        app_key: str | None = None,
        node_id: int | None = None,
        search_key: str | None = None,
        page_num: int = 1,
        page_size: int = 20,
        create_time_asc: bool | None = None,
    ) -> dict:
        return tasks.task_list(
            profile=profile,
            type=type,
            process_status=process_status,
            app_key=app_key,
            node_id=node_id,
            search_key=search_key,
            page_num=page_num,
            page_size=page_size,
            create_time_asc=create_time_asc,
        )

    @server.tool()
    def task_list_grouped(
        profile: str = DEFAULT_PROFILE,
        type: int = 1,
        process_status: int = 1,
        app_key: str | None = None,
        node_id: int | None = None,
        search_key: str | None = None,
        page_num: int = 1,
        page_size: int = 20,
    ) -> dict:
        return tasks.task_list_grouped(
            profile=profile,
            type=type,
            process_status=process_status,
            app_key=app_key,
            node_id=node_id,
            search_key=search_key,
            page_num=page_num,
            page_size=page_size,
        )

    @server.tool()
    def task_statistics(profile: str = DEFAULT_PROFILE, app_key: str | None = None) -> dict:
        return tasks.task_statistics(profile=profile, app_key=app_key)

    @server.tool()
    def task_urge(profile: str = DEFAULT_PROFILE, app_key: str = "", row_record_id: int = 0) -> dict:
        return tasks.task_urge(profile=profile, app_key=app_key, row_record_id=row_record_id)

    @server.tool(description=approvals._high_risk_tool_description(operation="approve", target="workflow task"))
    def task_approve(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        payload: dict | None = None,
    ) -> dict:
        return approvals.record_approve(profile=profile, app_key=app_key, apply_id=apply_id, payload=payload or {})

    @server.tool(description=approvals._high_risk_tool_description(operation="reject", target="workflow task"))
    def task_reject(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        payload: dict | None = None,
    ) -> dict:
        return approvals.record_reject(profile=profile, app_key=app_key, apply_id=apply_id, payload=payload or {})

    @server.tool()
    def task_rollback_candidates(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        audit_node_id: int = 0,
    ) -> dict:
        return approvals.record_rollback_candidates(
            profile=profile,
            app_key=app_key,
            apply_id=apply_id,
            audit_node_id=audit_node_id,
        )

    @server.tool()
    def task_rollback(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        payload: dict | None = None,
    ) -> dict:
        return approvals.record_rollback(profile=profile, app_key=app_key, apply_id=apply_id, payload=payload or {})

    @server.tool()
    def task_transfer_candidates(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        page_size: int = 20,
        page_num: int = 1,
        audit_node_id: int = 0,
        keyword: str | None = None,
    ) -> dict:
        return approvals.record_transfer_candidates(
            profile=profile,
            app_key=app_key,
            apply_id=apply_id,
            page_size=page_size,
            page_num=page_num,
            audit_node_id=audit_node_id,
            keyword=keyword,
        )

    @server.tool()
    def task_transfer(
        profile: str = DEFAULT_PROFILE,
        app_key: str = "",
        apply_id: int = 0,
        payload: dict | None = None,
    ) -> dict:
        return approvals.record_transfer(profile=profile, app_key=app_key, apply_id=apply_id, payload=payload or {})

    return server


mcp = build_user_server()


def main() -> None:
    mcp.run()


if __name__ == "__main__":
    main()
