"""플랫폼 관리 도구 — 데이터셋, 주석, think_tool."""

import json

from langchain.tools import tool

import sentinel.config as config
from sentinel.schema import ToolResult, AuditEvent, ActionType, Surface


@tool
def manage_datasets(
    action: str = "list",
    dataset_name: str = "",
    item_input: str = "",
    item_expected: str = "",
    source_trace_id: str = "",
    description: str = "",
) -> str:
    """데이터셋을 관리합니다 (list/create/add_item/list_items).

    Args:
        action: 작업 유형 (list, create, add_item, list_items)
        dataset_name: 데이터셋 이름 (create/add_item/list_items 시 필수)
        item_input: 아이템 입력 (add_item 시)
        item_expected: 기대 출력 (add_item 시)
        source_trace_id: 출처 트레이스 ID (add_item 시)
        description: 데이터셋 설명 (create 시)
    """
    from sentinel.services.governance import governance

    if action == "list":
        try:
            res = config.get_lf_client().api.datasets.list(limit=50)
            data = res.data if hasattr(res, "data") else res
            rows = [
                {"name": d.name, "description": getattr(d, "description", "")}
                for d in data
            ]
        except Exception as e:
            return ToolResult.fail(f"데이터셋 목록 조회 실패: {e}").to_json()
        return ToolResult.ok(data=rows, summary=f"데이터셋 {len(rows)}건 조회", count=len(rows)).to_json()

    elif action == "create":
        try:
            config.get_lf_client().api.datasets.create(name=dataset_name, description=description)
        except Exception as e:
            return ToolResult.fail(f"데이터셋 생성 실패: {e}").to_json()
        governance.record_action(AuditEvent(
            action=f"create_dataset:{dataset_name}",
            action_type=ActionType.MUTATE,
            actor="agent", surface=Surface.CLI,
            target_refs=[dataset_name], is_mutation=True,
        ))
        return ToolResult.ok(data={"name": dataset_name}, summary=f"데이터셋 '{dataset_name}' 생성 완료").to_json()

    elif action == "add_item":
        kwargs: dict = {
            "dataset_name": dataset_name,
            "input": (
                json.loads(item_input)
                if item_input.startswith("{")
                else item_input
            ),
        }
        if item_expected:
            kwargs["expected_output"] = item_expected
        if source_trace_id:
            kwargs["source_trace_id"] = source_trace_id
        try:
            config.get_lf_client().api.dataset_items.create(**kwargs)
        except Exception as e:
            return ToolResult.fail(f"데이터셋 아이템 추가 실패: {e}").to_json()
        governance.record_action(AuditEvent(
            action=f"add_dataset_item:{dataset_name}",
            action_type=ActionType.MUTATE,
            actor="agent", surface=Surface.CLI,
            target_refs=[dataset_name], is_mutation=True,
        ))
        return ToolResult.ok(data={"dataset": dataset_name}, summary=f"데이터셋 '{dataset_name}'에 아이템 추가 완료").to_json()

    elif action == "list_items":
        try:
            res = config.get_lf_client().api.dataset_items.list(
                dataset_name=dataset_name, limit=50
            )
            data = res.data if hasattr(res, "data") else res
            rows = [
                {"id": i.id, "input": str(getattr(i, "input", ""))[:200]}
                for i in data
            ]
        except Exception as e:
            return ToolResult.fail(f"데이터셋 아이템 조회 실패: {e}").to_json()
        return ToolResult.ok(data=rows, summary=f"아이템 {len(rows)}건 조회", count=len(rows)).to_json()

    return ToolResult.fail(f"알 수 없는 action: {action}").to_json()


@tool
def manage_annotations(
    action: str = "list",
    object_type: str = "TRACE",
    object_id: str = "",
    content: str = "",
    author: str = "sentinel-agent",
) -> str:
    """트레이스/observation에 코멘트(주석)를 관리합니다.

    Args:
        action: 작업 (list, create)
        object_type: 대상 타입 (TRACE 또는 OBSERVATION)
        object_id: 대상 ID
        content: 코멘트 내용 (create 시)
        author: 작성자 ID
    """
    from sentinel.services.governance import governance

    if action == "create":
        from langfuse.api.resources.comments.types import CreateCommentRequest

        try:
            config.get_lf_client().api.comments.create(
                request=CreateCommentRequest(
                    object_type=object_type,
                    object_id=object_id,
                    content=content,
                    author_user_id=author,
                )
            )
        except Exception as e:
            return ToolResult.fail(f"코멘트 작성 실패: {e}").to_json()
        governance.record_action(AuditEvent(
            action=f"create_annotation:{object_type}",
            action_type=ActionType.MUTATE,
            actor=author, surface=Surface.CLI,
            target_refs=[object_id], is_mutation=True,
        ))
        return ToolResult.ok(
            data={"object_type": object_type, "object_id": object_id},
            summary=f"코멘트 작성 완료: {object_type} {object_id[:12]}...",
        ).to_json()

    try:
        res = config.get_lf_client().api.comments.get(
            object_type=object_type, object_id=object_id
        )
        data = res.data if hasattr(res, "data") else res
        rows = [
            {
                "id": c.id,
                "content": c.content,
                "author": getattr(c, "author_user_id", ""),
            }
            for c in data
        ]
    except Exception as e:
        return ToolResult.fail(f"코멘트 조회 실패: {e}").to_json()
    return ToolResult.ok(data=rows, summary=f"코멘트 {len(rows)}건 조회", count=len(rows)).to_json()


@tool
def query_audit_log(
    limit: int = 20,
    run_id: str = "",
    tool_name: str = "",
    mutations_only: bool = False,
) -> str:
    """감사 로그를 조회합니다.

    Args:
        limit: 최대 조회 수
        run_id: 특정 run_id로 필터
        tool_name: 도구 이름 필터
        mutations_only: 변경 작업만 조회
    """
    from sentinel.audit import audit_log
    results = audit_log.query(
        limit=limit,
        run_id=run_id or None,
        tool_name=tool_name or None,
        mutations_only=mutations_only,
    )
    return ToolResult.ok(
        data=results,
        summary=f"감사 로그 {len(results)}건 조회",
        count=len(results),
    ).to_json()


@tool
def think_tool(thought: str) -> str:
    """전략적 반성 — 현재 상황을 분석하고 다음 행동을 계획합니다."""
    return ToolResult.ok(data={"thought": thought}, summary=f"Reflection recorded: {thought}").to_json()
