import json
from textwrap import dedent

import dataiku

from backend.utils.json_utils import extract_json_string
from backend.utils.logging_utils import get_logger

logger = get_logger(__name__)


class SmartConfigService:
    @staticmethod
    def generate_quick_agent_config(agent_name, description, system_prompt, llm_id):
        # Safely embed any user-provided fields as JSON so quotes/newlines are escaped correctly.
        user_fields = {}
        if agent_name:
            user_fields["agent_name"] = agent_name
        if description:
            user_fields["description"] = description
        if system_prompt:
            user_fields["system_prompt"] = system_prompt

        need_description = description is None or str(description).strip() == ""
        need_system_prompt = system_prompt is None or str(system_prompt).strip() == ""
        need_agent_name = agent_name is None or str(agent_name).strip() == "" or str(agent_name).strip() == "New Agent"

        # Dynamic list of fields the model must generate
        fields_to_generate = []
        if need_description:
            fields_to_generate.append("description (≤2 concise sentences)")
        if need_system_prompt:
            fields_to_generate.append("system_prompt (1 short paragraph: role, capabilities, tone, boundaries)")
        if need_agent_name:
            fields_to_generate.append("agent_name (≤3 words, relevant to purpose)")
        fields_to_generate.append("example_short_queries (3 items, ≤8 words each)")
        fields_to_generate.append("example_long_queries (3 items, 1–2 sentences each)")

        # Dynamic output contract: include missing fields only
        required_keys = [
            '"example_short_queries": list of 3 strings',
            '"example_long_queries": list of 3 strings',
        ]
        if need_description:
            required_keys.insert(0, '"description": string')
        if need_system_prompt:
            required_keys.append('"system_prompt": string')
        if need_agent_name:
            required_keys.append('"agent_name": string')

        # Build the instruction
        instructions = dedent(f"""
        You are creating assets for an AI agent.

        USER-PROVIDED FIELDS (use verbatim; do not rewrite):
        {json.dumps(user_fields, ensure_ascii=False, indent=2)}

        TASK
        Generate the missing items listed below so that **all pieces are consistent** with the user-provided fields and with each other:
        - {chr(10)+'- '.join(fields_to_generate)}

        CONTENT GUIDELINES
        - Keep the agent's purpose clear and specific to its domain.
        - Maintain a helpful, professional tone; avoid hype or fluff.
        - The system_prompt should set behavior, scope, tone, and guardrails (e.g., be honest about limitations; refuse unsafe requests; ask clarifying questions when needed).
        - Example queries must demonstrate the agent's core capabilities and typical user intents, and should vary in phrasing and specificity.
        - Ensure the agent_name is short (≤3 words), catchy, and reflective of the agent's purpose.
        - Do not include any sensitive, private, or confidential information.

        OUTPUT FORMAT (STRICT)
        Return ONLY a single JSON object (no prose, no markdown) with exactly these keys:
        - {chr(10)+'- '.join(required_keys)}

        JSON RULES
        - Use double quotes for all keys and string values.
        - Do not include null values or extra keys.
        - Do not include comments or trailing commas.
        """).strip()
        comp = dataiku.api_client().get_default_project().get_llm(llm_id).new_completion()
        comp.with_message(
            instructions,
            role="system",
        )
        comp.with_message(
            "Generate a valid JSON object according to the specified format.",
            role="user",
        )
        obj = {
            "description": description or None,
            "system_prompt": system_prompt or None,
            "example_short_queries": None,
            "example_long_queries": None,
            "agent_name": agent_name or None,
        }
        try:
            resp = comp.execute()
            if resp and resp.success:
                raw = resp.text.strip()
                obj = json.loads(extract_json_string(raw))
                logger.info(f"Generated quick agent config: {obj}")
                return obj
            else:
                raise Exception(f"Failed to generate stories prompt: {resp._raw.get('errorMessage') if resp else ''}")
        except Exception as e:
            logger.exception(f"Failed to generate chart params {e}")
            return obj
