import functools

import dataiku

from backend.config import get_config
from backend.utils.llm_utils import add_history_to_completion
from backend.utils.logging_utils import get_logger

logger = get_logger(__name__)


class StoriesService:
    @staticmethod
    @functools.lru_cache(maxsize=128)
    def get_agent_stories_workspace(aid: str):
        config = get_config()
        tool_agent_configurations = config.get("tool_agent_configurations")
        selected_agents = [
            agent_config["agent_id"] for agent_config in tool_agent_configurations if "agent_id" in agent_config
        ]
        ws_key = None
        if selected_agents and tool_agent_configurations:
            for agent in tool_agent_configurations:
                if agent["agent_id"] == aid and agent.get("enable_stories"):
                    ws_key = agent.get("stories_workspace")

        if ws_key:
            client = dataiku.api_client()
            workspace = client.get_workspace(ws_key)
            # make sure workspace exists
            try:
                workspace.get_settings()
                return workspace
            except Exception as e:
                logger.error("Workspace doesn't exist {e}")

        return None

    @staticmethod
    def generate_stories_prompt(llm_id, messages):
        client = dataiku.api_client()
        project = client.get_default_project()
        comp = project.get_llm(llm_id).new_completion()
        system_prompt = """
        You are a Prompt-For-Slides builder. Your only job is to read the conversation history, focus on the last user message and the last assistant answer, and transform them—optionally informed by earlier context—into a single, self-contained prompt addressed to a Slide Builder assistant.

        Priorities:
        1) Be maximally faithful to the last user message and the last assistant answer.
        2) Use conversation context only to clarify intent or fill harmless gaps; do not invent facts.
        3) Make the resulting prompt actionable: the Slide Builder should be able to create a complete presentation without further questions.

        What to include in the prompt you produce (in clearly labeled sections):
        - Objective & Audience
        - Key Messages (bullet points)
        - Inputs/Data (what datasets or evidence to use, with short descriptions and any IDs/paths if provided)
        - Scope & Constraints (languages, length/slide count, timebox, brand/tone, do/don’t)
        - Slide Structure (proposed outline with slide-by-slide one-liners)
        - Visual & Asset Guidance (charts, images, tables; where they come from)
        - Citations/Attributions (how to reference datasets/sources)

        Style:
        - Clear, concise, and directive. No meta-commentary. No apologies. No placeholders unless explicitly provided.
        - Prefer the language used in the last user message unless the user requested another.

        Output format:
        - Output ONLY the final prompt for the Slide Builder, with the section headers above. Do not add explanations or preambles.
        """

        comp.with_message(system_prompt, role="system")
        comp = add_history_to_completion(completion=comp, messages=messages)
        user_prompt = """
        From the conversation so far, identify:
        - The last user message
        - The last assistant answer
        - Any helpful earlier context (only if it clarifies intent)

        Then, based on the system instructions, produce the complete prompt for the Slide Builder assistant. The Slide Builder assistant has access to the datasets used to answer the last user query.

        Produce ONLY the final prompt addressed to the Slide Builder, using the sections defined in the system prompt. 
        The prompt will be passed directly to the slide builder assistant so return it ready to use with no additional texts or notes
        """
        comp.with_message(user_prompt, role="user")
        logger.info("Creating dataiku stories prompt")
        resp = comp.execute()
        if resp and resp.success:
            raw = resp.text.strip()
            logger.info(f"Dataiku stories prompt: {raw}")
            return raw
        else:
            raise Exception(f"Failed to generate stories prompt: {resp._raw.get('errorMessage') if resp else ''}")
