# -*- coding: utf-8 -*-
"""Export service for Auto Rubric feature.

This service handles exporting generated graders to various formats:
- Python code (.py)
- YAML configuration (.yaml)
- JSON configuration (.json)
"""

import json
from typing import Any

import yaml


class ExportService:
    """Service for exporting generated graders to various formats.

    This service converts grader configurations to different output formats
    suitable for direct use or integration with existing workflows.

    Example:
        >>> service = ExportService()
        >>> config = {"grader_name": "my_grader", "rubrics": "1. Accuracy...", ...}
        >>> python_code = service.export_python(config)
        >>> yaml_config = service.export_yaml(config)
    """

    def export_python(self, config: dict[str, Any]) -> str:
        """Export grader as Python code.

        Generates executable Python code that recreates the grader.

        Args:
            config: Grader configuration dictionary.

        Returns:
            Python code string.
        """
        grader_name = config.get("grader_name", "my_grader")
        task_description = config.get("task_description") or ""
        rubrics = config.get("rubrics") or ""
        grader_mode = config.get("grader_mode", "pointwise")
        language = config.get("language", "EN")
        min_score = config.get("min_score", 0)
        max_score = config.get("max_score", 5)
        model_name = config.get("model_name", "gpt-4o-mini")
        api_endpoint = config.get("api_endpoint") or ""

        # Escape special characters in strings
        rubrics_escaped = rubrics.replace('"""', r"\"\"\"").replace("\\", "\\\\")
        task_desc_escaped = task_description.replace('"', '\\"').replace("\n", "\\n")

        code = f'''# -*- coding: utf-8 -*-
"""Generated grader: {grader_name}

This grader was automatically generated by OpenJudge Auto Rubric.
Task: {task_desc_escaped[:100]}{"..." if len(task_description) > 100 else ""}
"""

from openjudge.graders.llm_grader import LLMGrader
from openjudge.graders.schema import GraderMode
from openjudge.models.openai_chat_model import OpenAIChatModel
from openjudge.models.schema.prompt_template import LanguageEnum


# Configure your model
model = OpenAIChatModel(
    model="{model_name}",
    base_url="{api_endpoint}",
    api_key="YOUR_API_KEY",  # Replace with your API key
)

# Generated rubrics
RUBRICS = """
{rubrics_escaped}
"""

# Create the grader
grader = LLMGrader(
    name="{grader_name}",
    model=model,
    mode=GraderMode.{grader_mode.upper()},
    rubrics=RUBRICS,
    language=LanguageEnum.{language.upper()},'''

        # Add score range only for pointwise mode
        if grader_mode.lower() == "pointwise":
            code += f"""
    min_score={min_score},
    max_score={max_score},"""

        code += """
)


# Example usage
async def evaluate_response(query: str, response: str):
    \"\"\"Evaluate a response using the generated grader.\"\"\"
    result = await grader.aevaluate(query=query, response=response)
    return {
        "score": result.score,
        "reason": result.reason,
    }


if __name__ == "__main__":
    import asyncio

    # Test the grader
    test_query = "Your test query here"
    test_response = "Response to evaluate"

    result = asyncio.run(evaluate_response(test_query, test_response))
    print(f"Score: {result['score']}")
    print(f"Reason: {result['reason']}")
"""
        return code

    def export_yaml(self, config: dict[str, Any]) -> str:
        """Export grader as YAML configuration.

        Args:
            config: Grader configuration dictionary.

        Returns:
            YAML configuration string.
        """
        yaml_config = {
            "grader": {
                "name": config.get("grader_name", "my_grader"),
                "type": "llm_grader",
                "mode": config.get("grader_mode", "pointwise"),
                "language": config.get("language", "EN"),
            },
            "rubrics": config.get("rubrics", ""),
            "task_description": config.get("task_description", ""),
            "model": {
                "name": config.get("model_name", "gpt-4o-mini"),
                "base_url": config.get("api_endpoint", ""),
            },
        }

        # Add score range only for pointwise mode
        if config.get("grader_mode", "pointwise").lower() == "pointwise":
            yaml_config["grader"]["min_score"] = config.get("min_score", 0)
            yaml_config["grader"]["max_score"] = config.get("max_score", 5)

        if config.get("scenario"):
            yaml_config["scenario"] = config.get("scenario")

        return yaml.dump(yaml_config, allow_unicode=True, sort_keys=False, default_flow_style=False)

    def export_json(self, config: dict[str, Any]) -> str:
        """Export grader as JSON configuration.

        Args:
            config: Grader configuration dictionary.

        Returns:
            JSON configuration string.
        """
        json_config = {
            "grader": {
                "name": config.get("grader_name", "my_grader"),
                "type": "llm_grader",
                "mode": config.get("grader_mode", "pointwise"),
                "language": config.get("language", "EN"),
            },
            "rubrics": config.get("rubrics", ""),
            "task_description": config.get("task_description", ""),
            "model": {
                "name": config.get("model_name", "gpt-4o-mini"),
                "base_url": config.get("api_endpoint", ""),
            },
        }

        # Add score range only for pointwise mode
        if config.get("grader_mode", "pointwise").lower() == "pointwise":
            json_config["grader"]["min_score"] = config.get("min_score", 0)
            json_config["grader"]["max_score"] = config.get("max_score", 5)

        if config.get("scenario"):
            json_config["scenario"] = config.get("scenario")

        return json.dumps(json_config, indent=2, ensure_ascii=False)

    def get_filename(self, grader_name: str, format_type: str) -> str:
        """Get the filename for export.

        Args:
            grader_name: Name of the grader.
            format_type: Export format ("python", "yaml", "json").

        Returns:
            Filename with appropriate extension.
        """
        # Sanitize grader name for filename
        safe_name = "".join(c if c.isalnum() or c in "_-" else "_" for c in grader_name)

        extensions = {
            "python": ".py",
            "yaml": ".yaml",
            "json": ".json",
        }
        return f"{safe_name}{extensions.get(format_type, '.txt')}"
