"""HallucinationCheck: Detect hallucinations in AI-generated output."""

from __future__ import annotations

from ai_qa.checks.registry import register
from ai_qa.core.check import BaseCheck
from ai_qa.core.context import Context
from ai_qa.core.result import CheckResult
from ai_qa.exceptions import ContextValidationError
from ai_qa.providers import get_provider

JUDGE_PROMPT = """You are an expert at detecting hallucinations in AI-generated text.

A hallucination is when the AI generates plausible-sounding but false or unfounded
information that is not grounded in the provided context.

Analyze the given input, context (if provided), and output to determine if the
output contains hallucinations.

Respond with a JSON object:
{
  "score": <float 0.0-1.0, where 1.0 means no hallucinations>,
  "evidence": "<explanation of any hallucinations found>"
}
"""


@register("hallucination")
class HallucinationCheck(BaseCheck):
    """Detect hallucinations in AI-generated output.

    Requires:
        - ctx.output: The AI-generated text to check
        - ctx.input: The prompt/query (optional but recommended)
        - ctx.context: Retrieved context chunks (optional but recommended for RAG)

    Hallucinations are false or unfounded claims made by the AI.

    Example:
        check = HallucinationCheck(threshold=0.8)
    """

    requires_llm = True
    version = "1.0.0"
    description = "Detect hallucinations in AI-generated output"

    def validate_context(self, ctx: Context) -> None:
        """Validate that output exists.

        Args:
            ctx: Context to validate.

        Raises:
            ContextValidationError: If output is missing.
        """
        if ctx.output is None:
            raise ContextValidationError(
                "HallucinationCheck requires ctx.output to be set.\n"
                "Example: Context(output='The AI response', "
                "context=['fact 1', 'fact 2'])"
            )

    def evaluate(self, ctx: Context) -> CheckResult:
        """Evaluate output for hallucinations using LLM.

        Args:
            ctx: Context with output to validate.

        Returns:
            CheckResult with hallucination score and evidence.
        """
        self.validate_context(ctx)

        provider = get_provider()

        # Build context string if available
        context_str = ""
        if ctx.context:
            context_str = "\n".join(f"- {c}" for c in ctx.context)

        prompt = f"""INPUT: {ctx.input or 'N/A'}

CONTEXT:
{context_str or 'None provided'}

OUTPUT:
{ctx.output}

Analyze the output for hallucinations. Score higher if the output is grounded in facts
and the input/context. Score lower if it contains unfounded claims."""

        resp = provider.judge(system=JUDGE_PROMPT, user=prompt)

        return CheckResult(
            name=self.name,
            score=resp.get("score", 0.5),
            passed=resp.get("score", 0.5) >= self.threshold,
            threshold=self.threshold,
            evidence=resp.get("evidence", ""),
            cost_usd=resp.get("cost_usd", 0.0),
            tokens_used=resp.get("tokens", {}),
            check_version=self.version,
        )
