"""Prompt builder factory for generating AI agent instructions"""

import sys
from datetime import datetime
from typing import List, Optional


class PromptBuilder:
    """Chainable prompt builder for AI agent instructions"""
    
    def __init__(self):
        self._base_prompt: Optional[str] = None
        self._additional_prompts: List[str] = []
    
    def base(self, prompt: str) -> "PromptBuilder":
        """Set base/root prompt
        
        Args:
            prompt: Base prompt text
            
        Returns:
            Self for chaining
        """
        self._base_prompt = prompt
        return self
    
    def add(self, prompt: str) -> "PromptBuilder":
        """Add an additional prompt fragment
        
        Args:
            prompt: Prompt fragment to add
            
        Returns:
            Self for chaining
        """
        if prompt:
            self._additional_prompts.append(prompt)
        return self
    
    def add_if(self, condition: bool, prompt: str) -> "PromptBuilder":
        """Conditionally add a prompt fragment
        
        Args:
            condition: If True, add the prompt
            prompt: Prompt fragment to add
            
        Returns:
            Self for chaining
        """
        if condition and prompt:
            self._additional_prompts.append(prompt)
        return self
    
    def add_builder(self, builder: "PromptBuilder") -> "PromptBuilder":
        """Add another builder's content
        
        Args:
            builder: Another PromptBuilder to merge
            
        Returns:
            Self for chaining
        """
        if builder._base_prompt and not self._base_prompt:
            self._base_prompt = builder._base_prompt
        self._additional_prompts.extend(builder._additional_prompts)
        return self
    
    def prepend(self, prompt: str) -> "PromptBuilder":
        """Prepend a prompt fragment (appears before additions)
        
        Args:
            prompt: Prompt to prepend
            
        Returns:
            Self for chaining
        """
        if prompt:
            self._additional_prompts.insert(0, prompt)
        return self
    
    def clear(self) -> "PromptBuilder":
        """Clear all prompts
        
        Returns:
            Self for chaining
        """
        self._base_prompt = None
        self._additional_prompts.clear()
        return self
    
    def build(self) -> str:
        """Build final prompt string
        
        Returns:
            Combined prompt text
        """
        parts = []
        
        if self._base_prompt:
            parts.append(self._base_prompt.strip())
        
        for p in self._additional_prompts:
            if p:
                parts.append(p.strip())
        
        return "\n\n".join(parts)
    
    def __str__(self) -> str:
        return self.build()
    
    def __len__(self) -> int:
        return len(self.build())


def create_prompt_builder() -> PromptBuilder:
    """Create a new prompt builder instance
    
    Returns:
        New PromptBuilder
    """
    return PromptBuilder()


class PromptFactory:
    """Static factory for creating AI agent prompts"""
    
    @staticmethod
    def create_base_prompt() -> str:
        """Create base system prompt using PromptBuilder
        
        Returns:
            Base prompt string
        """
        current_date = datetime.now().strftime("%Y-%m-%d %H:%M")
        platform_name = sys.platform
        
        from diona.project.agent.globals import list_all_skills, SkillSource
        skills = list_all_skills()
        
        skills_info = []
        for skill in skills:
            source_label = "built-in" if skill.source == SkillSource.BUILTIN else "user"
            extra_str = ""
            if skill.extra:
                extra_parts = [f"{k}: {v}" for k, v in skill.extra.items()]
                extra_str = f" | {', '.join(extra_parts)}"
            skills_info.append(f"- {skill.name}: {skill.description} ({source_label}){extra_str}")
        
        skills_text = "\n".join(skills_info) if skills_info else "No skills available."
        
        builder = (
            create_prompt_builder()
            .base("You name is Fairy, You are a helpful AI assistant.")
            .add("Remember: When you don't know how to do something or cannot do it directly, "
                 "check available tools and handoff agents first before giving an answer.")
            .add("Notice: If you want to run a python program, you should use the python_sandbox_tool "
                 "instead of the shell tool. The shell tool is not designed to run python programs "
                 "and is restricted to shell commands only.")
            .add(f"Notice: You can use skills from the skills_tool. "
                 f"Available skills:\n{skills_text}")
            .add("Notice: If you want to run a skill script, you should use the skill_script_tool "
                 "instead of the shell tool. The shell tool is not designed to run skill scripts ")
            .add(f"System Info: Running on {platform_name}. Current date: {current_date}. Begin.")
        )
        
        return builder.build()
    
    @staticmethod
    def create_builder() -> PromptBuilder:
        """Create a new PromptBuilder
        
        Returns:
            New PromptBuilder
        """
        return PromptBuilder()
    
    @staticmethod
    def get_default_instructions() -> str:
        """Get default instructions for CoreAgent
        
        Returns:
            Default instructions string
        """
        return PromptFactory.create_base_prompt()


class PromptManager:
    """Centralized prompt management with presets"""
    
    _presets: dict = {}
    
    @classmethod
    def register_preset(cls, name: str, builder: PromptBuilder):
        """Register a prompt preset
        
        Args:
            name: Preset name
            builder: PromptBuilder instance
        """
        cls._presets[name] = builder
    
    @classmethod
    def get_preset(cls, name: str) -> Optional[PromptBuilder]:
        """Get a registered preset
        
        Args:
            name: Preset name
            
        Returns:
            PromptBuilder or None
        """
        return cls._presets.get(name)
    
    @classmethod
    def create_from_preset(cls, name: str) -> PromptBuilder:
        """Create a new builder from preset
        
        Args:
            name: Preset name
            
        Returns:
            New PromptBuilder from preset
        """
        preset = cls.get_preset(name)
        if preset:
            builder = PromptBuilder()
            builder.add_builder(preset)
            return builder
        return PromptBuilder()
