"""
Write-enabled MCP tools for Dynamics 365 / Dataverse.

All mutations require plan_hash generated by the corresponding *.plan tool.
"""

from __future__ import annotations

from typing import Any, Callable, Dict, List, Tuple

from g_gremlin import dynamics_dataverse_mcp

ToolTuple = Tuple[str, Callable[..., Dict[str, Any]], str]


def _validate_hash(operation: str, payload: Dict[str, Any], plan_hash: str, tool_name: str) -> str:
    return dynamics_dataverse_mcp.enforce_plan_hash(
        operation=operation,
        payload=payload,
        plan_hash=plan_hash,
        tool_name=tool_name,
    )


def dynamics_create_record_apply(
    table: str,
    record: Dict[str, Any],
    plan_hash: str,
    profile: str | None = None,
) -> Dict[str, Any]:
    payload = {"table": table, "record": record}
    validated = _validate_hash("create_record", payload, plan_hash, "dynamics.create_record.apply")
    client = dynamics_dataverse_mcp.create_dataverse_client(profile=profile)
    result = client.create_record(table=table, record=record)
    return {"plan_hash": validated, "result": result}


def dynamics_update_record_apply(
    table: str,
    record_id: str,
    fields: Dict[str, Any],
    plan_hash: str,
    profile: str | None = None,
) -> Dict[str, Any]:
    payload = {"table": table, "record_id": record_id, "fields": fields}
    validated = _validate_hash("update_record", payload, plan_hash, "dynamics.update_record.apply")
    client = dynamics_dataverse_mcp.create_dataverse_client(profile=profile)
    result = client.update_record(table=table, record_id=record_id, fields=fields)
    return {"plan_hash": validated, "result": result}


def dynamics_delete_record_apply(
    table: str,
    record_id: str,
    plan_hash: str,
    profile: str | None = None,
) -> Dict[str, Any]:
    payload = {"table": table, "record_id": record_id}
    validated = _validate_hash("delete_record", payload, plan_hash, "dynamics.delete_record.apply")
    client = dynamics_dataverse_mcp.create_dataverse_client(profile=profile)
    result = client.delete_record(table=table, record_id=record_id)
    return {"plan_hash": validated, "result": result}


def dynamics_create_table_apply(
    definition: Dict[str, Any],
    plan_hash: str,
    profile: str | None = None,
) -> Dict[str, Any]:
    payload = {"definition": definition}
    validated = _validate_hash("create_table", payload, plan_hash, "dynamics.create_table.apply")
    client = dynamics_dataverse_mcp.create_dataverse_client(profile=profile)
    result = client.create_table(definition=definition)
    return {"plan_hash": validated, "result": result}


def dynamics_update_table_apply(
    table: str,
    definition: Dict[str, Any],
    plan_hash: str,
    profile: str | None = None,
) -> Dict[str, Any]:
    payload = {"table": table, "definition": definition}
    validated = _validate_hash("update_table", payload, plan_hash, "dynamics.update_table.apply")
    client = dynamics_dataverse_mcp.create_dataverse_client(profile=profile)
    result = client.update_table(table=table, definition=definition)
    return {"plan_hash": validated, "result": result}


def dynamics_delete_table_apply(
    table: str,
    plan_hash: str,
    profile: str | None = None,
) -> Dict[str, Any]:
    payload = {"table": table}
    validated = _validate_hash("delete_table", payload, plan_hash, "dynamics.delete_table.apply")
    client = dynamics_dataverse_mcp.create_dataverse_client(profile=profile)
    result = client.delete_table(table=table)
    return {"plan_hash": validated, "result": result}


def get_tools() -> List[ToolTuple]:
    return [
        ("dynamics.create_record.apply", dynamics_create_record_apply, "Apply Dataverse create_record (requires plan_hash)."),
        ("dynamics.update_record.apply", dynamics_update_record_apply, "Apply Dataverse update_record (requires plan_hash)."),
        ("dynamics.delete_record.apply", dynamics_delete_record_apply, "Apply Dataverse delete_record (requires plan_hash)."),
        ("dynamics.create_table.apply", dynamics_create_table_apply, "Apply Dataverse create_table (requires plan_hash)."),
        ("dynamics.update_table.apply", dynamics_update_table_apply, "Apply Dataverse update_table (requires plan_hash)."),
        ("dynamics.delete_table.apply", dynamics_delete_table_apply, "Apply Dataverse delete_table (requires plan_hash)."),
    ]
