"""도구 출력 표준 스키마."""
from __future__ import annotations

import json
import uuid
from dataclasses import asdict, dataclass, field
from datetime import datetime, timezone
from enum import Enum
from typing import Any


# ---------------------------------------------------------------------------
# 기존 ToolResult
# ---------------------------------------------------------------------------


@dataclass
class ToolResult:
    """도구 출력 표준 envelope."""

    success: bool
    data: Any = None
    error: str | None = None
    summary: str = ""
    count: int | None = None
    total: int | None = None
    page: int | None = None
    has_more: bool = False

    def to_json(self) -> str:
        """JSON 문자열로 직렬화."""
        d = {k: v for k, v in asdict(self).items() if v is not None}
        return json.dumps(d, ensure_ascii=False, indent=2, default=str)

    @staticmethod
    def ok(
        data: Any,
        summary: str = "",
        count: int | None = None,
        total: int | None = None,
        page: int | None = None,
        has_more: bool = False,
    ) -> ToolResult:
        """성공 결과."""
        return ToolResult(
            success=True,
            data=data,
            summary=summary,
            count=count,
            total=total,
            page=page,
            has_more=has_more,
        )

    @staticmethod
    def fail(error: str, data: Any = None) -> ToolResult:
        """실패 결과."""
        return ToolResult(success=False, error=error, data=data)


# ---------------------------------------------------------------------------
# Action types
# ---------------------------------------------------------------------------


class ActionType(str, Enum):
    READ = "read"
    ANALYZE = "analyze"
    DRAFT = "draft"
    MUTATE = "mutate"
    PUBLISH = "publish"


class Surface(str, Enum):
    WEB = "web"
    CLI = "cli"
    MCP = "mcp"
    SCHEDULER = "scheduler"


# ---------------------------------------------------------------------------
# ActionResult — 서비스 계층 반환 표준
# ---------------------------------------------------------------------------


@dataclass
class ActionResult:
    """서비스 계층 액션 결과."""

    success: bool
    action_type: ActionType
    summary: str = ""
    data: Any = None
    evidence_refs: list[str] = field(default_factory=list)
    approval_required: bool = False
    next_actions: list[str] = field(default_factory=list)

    def to_dict(self) -> dict:
        d = asdict(self)
        d["action_type"] = self.action_type.value
        return d


# ---------------------------------------------------------------------------
# AuditEvent — 감사 이벤트
# ---------------------------------------------------------------------------


@dataclass
class AuditEvent:
    """감사 이벤트 데이터."""

    action: str
    action_type: ActionType
    actor: str = "system"
    surface: Surface = Surface.WEB
    target_refs: list[str] = field(default_factory=list)
    is_mutation: bool = False
    status: str = "success"
    error: str | None = None
    metadata: dict | None = None


# ---------------------------------------------------------------------------
# JobRecord — 백그라운드 작업
# ---------------------------------------------------------------------------


class JobStatus(str, Enum):
    QUEUED = "queued"
    RUNNING = "running"
    SUCCEEDED = "succeeded"
    FAILED = "failed"


@dataclass
class JobRecord:
    """백그라운드 작업 레코드."""

    id: str = field(default_factory=lambda: uuid.uuid4().hex[:12])
    type: str = ""
    status: JobStatus = JobStatus.QUEUED
    params: dict = field(default_factory=dict)
    result: Any = None
    created_at: str = field(
        default_factory=lambda: datetime.now(timezone.utc).isoformat()
    )
    started_at: str | None = None
    completed_at: str | None = None


# ---------------------------------------------------------------------------
# ApprovalRequest — 승인 요청 데이터
# ---------------------------------------------------------------------------


@dataclass
class ApprovalRequest:
    """승인 요청 데이터."""

    request_type: str
    action_summary: str
    params: dict = field(default_factory=dict)
    evidence_refs: list[str] = field(default_factory=list)
    actor: str = "system"
    surface: Surface = Surface.WEB


# ---------------------------------------------------------------------------
# Improvement Loop — Draft Artifact 스키마
# ---------------------------------------------------------------------------


@dataclass
class DatasetDraftItem:
    """Dataset draft 개별 항목."""

    source_trace_id: str
    trace_name: str = ""
    input: str = ""
    expected_output: str = ""


@dataclass
class DatasetDraft:
    """Dataset draft artifact."""

    type: str = "dataset"
    source_trace_ids: list[str] = field(default_factory=list)
    items: list[DatasetDraftItem] = field(default_factory=list)
    review_status: str = "pending"


@dataclass
class EvaluatorCriteria:
    """Evaluator draft 평가 기준."""

    name: str = ""
    description: str = ""
    scoring_rubric: str = ""


@dataclass
class EvaluatorDraft:
    """Evaluator draft artifact."""

    type: str = "evaluator"
    target_pattern: str = ""
    criteria: EvaluatorCriteria = field(default_factory=EvaluatorCriteria)
    examples: list[dict] = field(default_factory=list)
    review_status: str = "pending"


@dataclass
class PromptChangeDraft:
    """Prompt 변경 draft artifact."""

    type: str = "prompt_change"
    prompt_ref: str = ""
    rationale: str = ""
    before: str = ""
    after: str = ""
    expected_impact: str = ""
    review_status: str = "pending"


@dataclass
class ImprovementCandidate:
    """개선 후보 — trace 분석에서 도출."""

    source_type: str = ""
    source_refs: list[str] = field(default_factory=list)
    failure_summary: str = ""
    proposed_actions: list[str] = field(default_factory=list)
    confidence: float = 0.0
