"""Draft 서비스 — dataset/evaluator/prompt 변경 초안 생성."""

import json
import logging
import uuid
from datetime import datetime, timezone

import sentinel.config as config
from sentinel.integrations.langfuse_gateway import LangfuseGateway

logger = logging.getLogger("sentinel.services.draft")


class DraftService:
    """Improvement Loop의 draft artifact를 생성합니다."""

    def __init__(self, gateway: LangfuseGateway | None = None):
        self.gw = gateway or LangfuseGateway()

    def create_dataset_draft(self, trace_ids: list[str]) -> dict:
        """trace input/output을 dataset item으로 변환하는 draft를 생성합니다."""
        items = []
        for tid in trace_ids[:20]:
            try:
                t = self.gw.get_trace(tid)
                items.append({
                    "source_trace_id": tid,
                    "input": str(t.get("input", ""))[:2000],
                    "expected_output": str(t.get("output", ""))[:2000],
                    "trace_name": t.get("name"),
                })
            except Exception:
                logger.warning("trace 조회 실패: %s", tid)

        draft = {
            "id": uuid.uuid4().hex[:12],
            "type": "dataset",
            "source_trace_ids": trace_ids,
            "items": items,
            "review_status": "pending",
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
        return draft

    def create_eval_draft(self, cluster_summary: dict) -> dict:
        """failure pattern을 기반으로 evaluator criterion 초안을 생성합니다."""
        patterns = cluster_summary.get("failure_patterns", [])
        summary = cluster_summary.get("summary", "")

        prompt = (
            "아래 failure 패턴을 기반으로 LLM evaluator criterion을 생성하세요.\n\n"
            f"<DATA>\nsummary: {summary}\npatterns: {patterns}\n</DATA>\n\n"
            "JSON 형식:\n"
            '{"name": "criterion 이름", "description": "설명", '
            '"scoring_rubric": "0-1 점수 기준", '
            '"examples": [{"input": "...", "good_output": "...", "bad_output": "..."}]}'
        )

        try:
            resp = config.get_model().invoke(prompt)
            criterion = json.loads(resp.content)
        except Exception:
            criterion = {
                "name": f"auto_eval_{uuid.uuid4().hex[:6]}",
                "description": summary,
                "scoring_rubric": "0=fail, 0.5=partial, 1=pass",
                "examples": [],
            }

        draft = {
            "id": uuid.uuid4().hex[:12],
            "type": "evaluator",
            "target_pattern": summary,
            "criteria": criterion,
            "review_status": "pending",
            "created_at": datetime.now(timezone.utc).isoformat(),
            "source_cluster": cluster_summary.get("trace_ids", []),
        }
        return draft

    def create_prompt_change_draft(
        self, prompt_name: str, evidence: list[str] | None = None
    ) -> dict:
        """현재 prompt + evidence를 기반으로 LLM 개선안을 생성합니다."""
        # 현재 prompt 조회
        try:
            current = self.gw.get_prompt(prompt_name)
            current_text = current.get("prompt", "")
        except Exception:
            current_text = ""
            current = {"name": prompt_name}

        evidence_text = "\n".join(evidence or [])

        prompt = (
            "프롬프트 엔지니어로서 다음 프롬프트를 개선하세요.\n\n"
            f"<DATA role=\"current\">\n{current_text}\n</DATA>\n\n"
            f"<DATA role=\"evidence\">\n{evidence_text}\n</DATA>\n\n"
            "JSON 형식:\n"
            '{"improved_prompt": "개선된 전문", "rationale": "변경 이유", '
            '"expected_impact": "예상 개선 효과", "changes": ["변경1", ...]}'
        )

        try:
            resp = config.get_model().invoke(prompt)
            improvement = json.loads(resp.content)
        except Exception:
            improvement = {
                "improved_prompt": current_text,
                "rationale": "자동 분석 실패",
                "expected_impact": "N/A",
                "changes": [],
            }

        draft = {
            "id": uuid.uuid4().hex[:12],
            "type": "prompt_change",
            "prompt_ref": prompt_name,
            "before": current_text,
            "after": improvement.get("improved_prompt", ""),
            "rationale": improvement.get("rationale", ""),
            "expected_impact": improvement.get("expected_impact", ""),
            "changes": improvement.get("changes", []),
            "review_status": "pending",
            "created_at": datetime.now(timezone.utc).isoformat(),
            "evidence_refs": evidence or [],
        }
        return draft

    def create_approval_packet(self, drafts: list[dict]) -> dict:
        """여러 draft를 하나의 approval request로 묶습니다."""
        from sentinel.schema import ApprovalRequest, Surface
        from sentinel.services.governance import governance

        draft_ids = [d["id"] for d in drafts]
        draft_types = list({d["type"] for d in drafts})

        req = ApprovalRequest(
            request_type="improvement_drafts",
            action_summary=f"{len(drafts)}개 draft 승인 요청 ({', '.join(draft_types)})",
            params={"draft_ids": draft_ids, "draft_types": draft_types},
            evidence_refs=draft_ids,
            actor="system",
            surface=Surface.WEB,
        )

        approval_id = governance.require_approval(req)
        return {
            "approval_id": approval_id,
            "draft_ids": draft_ids,
            "draft_count": len(drafts),
        }
