"""
Kite CLI - Scaffold agents and validate skill files.

Usage:
    kite init --type=agent --name=my_agent
    kite init --type=workflow --from-md=skill.md --name=my_workflow
    kite validate skills/my_skill.md
"""

import argparse
import os
import sys
import textwrap


# =============================================================================
# TEMPLATES
# =============================================================================

TEMPLATE_ENV = textwrap.dedent("""\
    # Kite Agent Configuration
    LLM_PROVIDER=groq
    LLM_MODEL=llama-3.3-70b-versatile
    GROQ_API_KEY=your_key_here

    # Optional
    # OPENAI_API_KEY=your_key_here
    # ANTHROPIC_API_KEY=your_key_here
""")

TEMPLATE_REQUIREMENTS = textwrap.dedent("""\
    kite-agent>=0.2.1
""")

TEMPLATE_SKILL_MD = textwrap.dedent("""\
    ---
    name: {name}
    description: A skill for {name}
    system_prompt: "You are an AI assistant. Use your tools to help the user."
    safety:
      forbidden_patterns: ["rm -rf", "DROP TABLE", "DELETE FROM"]
      max_retries: 3
      timeout: 30
    ---

    ## Tool: hello
    Say hello to the user.

    ### Parameters
    - name (str, required): The name to greet

    ### Script
    ```python
    result = f"Hello, {{name}}! Welcome to {name}."
    ```
""")


def _generate_agent_main(name: str) -> str:
    """Generate main.py for an agent project."""
    return textwrap.dedent(f"""\
        \"\"\"
        {name} - Agent powered by Kite Framework
        Generated with: kite init --type=agent
        \"\"\"

        import asyncio
        from kite import Kite

        async def main():
            ai = Kite()
            
            # Define tools
            @ai.tool(description="Say hello")
            def greet(name: str):
                return f"Hello, {{name}}!"
            
            # Create agent
            agent = ai.create_agent(
                name="{name}",
                system_prompt="You are a helpful assistant. Use tools when needed.",
                tools=[ai.tools.get("greet")],
                verbose=True
            )
            
            print(f"Agent '{name}' ready!")
            
            # Interactive loop
            print("\\nType your request (or 'quit' to exit):")
            while True:
                user_input = input("\\n> ")
                if user_input.lower() in ("quit", "exit", "q"):
                    break
                result = await agent.run(user_input)
                print(f"\\n{{result}}")

        if __name__ == "__main__":
            asyncio.run(main())
    """)


def _generate_workflow_main(name: str) -> str:
    """Generate main.py for a workflow project."""
    return textwrap.dedent(f"""\
        \"\"\"
        {name} - Workflow powered by Kite Framework
        Generated with: kite init --type=workflow
        \"\"\"

        import asyncio
        from kite import Kite

        async def main():
            ai = Kite()
            
            # Define tools
            @ai.tool
            def process_data(data: str):
                \"\"\"Process input data.\"\"\"
                return f"Processed: {{data}}"
            
            # Create pipeline agents
            planner = ai.create_agent(
                name="Planner",
                system_prompt="You plan workflow steps.",
                verbose=True
            )
            
            executor = ai.create_agent(
                name="Executor",
                system_prompt="You execute planned steps using tools.",
                tools=[ai.tools.get("process_data")],
                verbose=True
            )
            
            # Run
            plan = await planner.run("Plan how to process user data")
            result = await executor.run(f"Execute: {{plan}}")
            print(f"\\nResult: {{result}}")

        if __name__ == "__main__":
            asyncio.run(main())
    """)



def _generate_tool_main(name: str) -> str:
    """Generate main.py for a standalone tool module."""
    return textwrap.dedent(f"""\
        \"\"\"
        {name} - Standalone Tool for Kite Framework
        Generated with: kite init --type=tool
        \"\"\"

        from kite import Tool

        def {name}_function(input_text: str) -> str:
            \"\"\"
            {name} tool - describe what this tool does.
            
            Args:
                input_text: The input to process
                
            Returns:
                The processed result
            \"\"\"
            # TODO: Implement your tool logic here
            return f"Result from {name}: {{input_text}}"

        # Create the tool instance
        tool = Tool(
            name="{name}",
            func={name}_function,
            description="{name} tool"
        )

        # For testing
        if __name__ == "__main__":
            result = tool.execute(input_text="test input")
            print(f"Tool result: {{result}}")
    """)


# =============================================================================
# COMMANDS
# =============================================================================

def cmd_init(args):
    """Handle 'kite init' command."""
    project_name = args.name or "my_agent"
    project_type = args.type or "agent"
    
    # Create project directory
    project_dir = os.path.join(os.getcwd(), project_name)
    
    if os.path.exists(project_dir):
        print(f"❌ Directory '{project_name}' already exists!")
        sys.exit(1)
    
    os.makedirs(project_dir)
    print(f"📁 Creating project: {project_name}/")
    
    # Generate main.py
    if project_type == "agent":
        main_content = _generate_agent_main(project_name)
    elif project_type == "workflow":
        main_content = _generate_workflow_main(project_name)
    elif project_type == "tool":
        main_content = _generate_tool_main(project_name)
    else:
        print(f"❌ Unknown type: {project_type}. Use: agent, workflow, tool")
        sys.exit(1)
    
    main_file = os.path.join(project_dir, "main.py")
    with open(main_file, "w", encoding="utf-8") as f:
        f.write(main_content)
    print(f"   ├── main.py ({project_type})")
    
    # .env.example
    env_file = os.path.join(project_dir, ".env.example")
    with open(env_file, "w", encoding="utf-8") as f:
        f.write(TEMPLATE_ENV)
    print(f"   ├── .env.example")
    
    # requirements.txt
    req_file = os.path.join(project_dir, "requirements.txt")
    with open(req_file, "w", encoding="utf-8") as f:
        f.write(TEMPLATE_REQUIREMENTS)
    print(f"   └── requirements.txt")
    
    print(f"\n✅ Project '{project_name}' created successfully!")
    print(f"\nNext steps:")
    print(f"   cd {project_name}")
    print(f"   cp .env.example .env    # Configure your API keys")
    print(f"   pip install -r requirements.txt")
    print(f"   python main.py")


def cmd_compile(args):
    """Handle 'kite compile' command."""
    skill_path = args.skill_file
    out_path = args.out
    
    if not os.path.exists(skill_path):
        print(f"❌ File not found: {skill_path}")
        sys.exit(1)
        
    print(f"🧠 Using AI Compiler to translate {skill_path} to Python workflow...")
    
    with open(skill_path, "r", encoding="utf-8") as f:
        skill_content = f.read()

    import asyncio
    from kite import Kite
    
    async def _compile():
        ai = Kite()
        
        prompt = f"""
You are an expert Python engineer generating code for the Kite Framework.

Read the following Kite Skill Definition (Markdown) and translate it into a structured
Multi-Agent Python script using the `kite` library. 

CRITICAL: DO NOT MOCK THE KITE FRAMEWORK. You must import and use the real Kite SDK.
Here is the correct API usage for the Kite framework:
```python
import asyncio
from typing import Dict, Any
from kite import Kite

async def main():
    ai = Kite()
    context: Dict[str, Any] = {{}}
    
    @ai.tool(description="Do something")
    def my_tool(arg: str):
        return f"Did {{arg}}"
        
    gatherer = ai.create_agent(
        name="Gatherer",
        system_prompt="You gather information...",
        tools=[ai.tools.get("my_tool")],
        verbose=True
    )
    
    result_dict = await gatherer.run("Instruction")
    print(result_dict.get("response", ""))

if __name__ == "__main__":
    asyncio.run(main())
```

Design multiple specific agents (e.g. Gatherer, Analyst, etc. based on the domain) 
that work together in a pipeline to execute the skill. Define any helpful mock @ai.tool 
functions for them to use.

Output ONLY raw valid Python code. No markdown formatting blocks around it.

Skill Definition:
{skill_content}
"""
        
        print("⏳ Translating skill into Kite workflow representation... (this may take a minute)")
        agent = ai.create_agent(
            name="Compiler",
            system_prompt="You generate code. Return ONLY raw Python code text, no markdown fencing, no explanation.",
            verbose=False
        )
        
        result = await agent.run(prompt)
        text = result.get("response", "").strip()
        
        # Robust LLM failure detection
        if not result.get("success", True):
            error_msg = result.get("error", "Unknown error")
            print(f"❌ Compilation failed: {error_msg}")
            print("   Check your API key and LLM_PROVIDER in .env")
            sys.exit(1)
            
        if not text or text.lower().startswith("error") or "connection error" in text.lower():
            print(f"❌ Compilation failed: {text or 'No response from LLM'}")
            print("   Check your API key and LLM_PROVIDER in .env")
            sys.exit(1)

        # Clean up formatting if it accidentally included markdown
        if text.startswith("```python"):
            text = text[9:]
        elif text.startswith("```"):
            text = text[3:]
        if text.endswith("```"):
            text = text[:-3]
        text = text.strip()

        # Final check — make sure output looks like Python
        if not any(kw in text for kw in ["import", "def ", "async ", "class "]):
            print(f"❌ Compiled output doesn't look like valid Python code.")
            print(f"   LLM response: {text[:200]}")
            sys.exit(1)

        with open(out_path, "w", encoding="utf-8") as f:
            f.write(text)
        
        print(f"✅ Successfully compiled {skill_path} to {out_path}")
        print(f"   Run: python {out_path}")

    asyncio.run(_compile())


def cmd_generate(args):
    """Handle 'kite generate' command."""
    
    prompt_idea = args.prompt
    out_path = args.out
    
    print(f"🧠 Using AI Generator to build Kite application from your idea...")
    
    import asyncio
    from kite import Kite
    
    async def _generate():
        ai = Kite()
        
        system_instructions = f"""
You are an expert Python engineer generating code for the Kite Framework.

Create a complete, runnable Multi-Agent Python script using the `kite` library based on the user's idea below.

CRITICAL: DO NOT MOCK THE KITE FRAMEWORK. You must import and use the real Kite SDK.
Here is the correct API usage for the Kite framework:
```python
import asyncio
from typing import Dict, Any
from kite import Kite

async def main():
    ai = Kite()
    context: Dict[str, Any] = {{}}
    
    @ai.tool(description="Do something")
    def my_tool(arg: str):
        return f"Did {{arg}}"
        
    gatherer = ai.create_agent(
        name="Gatherer",
        system_prompt="You gather information...",
        tools=[ai.tools.get("my_tool")],
        verbose=True
    )
    
    result_dict = await gatherer.run("Instruction")
    print(result_dict.get("response", ""))

if __name__ == "__main__":
    asyncio.run(main())
```

Design multiple specific agents (e.g. Gatherer, Analyst, etc. based on the domain) 
that work together in a pipeline to execute the idea. 

CRITICAL - MOCKING EXTERNAL SERVICES:
If your tools need to talk to the real world (e.g. GitHub, Web Scraping, Database), DO NOT JUST RETURN MOCK STRINGS. 
You must write the actual Python code to perform the behavior securely!
- Use STANDARD LIBRARIES ONLY when possible (e.g., `urllib.request`, `json`, `sqlite3`, `re`).
- DO NOT use external pip packages like `aiohttp`, `textblob`, or `beautifulsoup4` unless absolutely necessary, to avoid `ModuleNotFoundError`.
- If you need to use playwright inside a tool, you MUST use `sync_playwright` from `playwright.sync_api` because tools in Kite are synchronous functions running inside an existing event loop. DO NOT use `async_playwright` or `asyncio.run()` inside a tool, it will crash.
- When automating Google Search with Playwright, DO NOT click the search button (e.g., `btnK`) as it is often hidden by the dropdown. Instead, fill the input (`textarea[name="q"]`) and use `page.keyboard.press("Enter")`.
- ALWAYS wait for navigation or specific selectors after an action. For Google results, wait for `div#search` before trying to extract links.
- If you need to search Google or interact with websites that block standard requests, always use `sync_playwright` to navigate, do not use `urllib` as it will get a 403 Forbidden.
- CRITICAL: Automatically generated agent scripts must always pass an instruction string to `agent.run()`. NEVER write `await gatherer.run()`, it must be `await gatherer.run("Some instruction here")`.
- Provide clear `# TODO: Enter your API key here` comments so the user just has to provide keys and execute.
Do not mock things unless explicitly asked to. Use proper exception handling.

Output ONLY raw valid Python code. No markdown formatting blocks around it.

User's Idea:
{prompt_idea}
"""
        
        print("⏳ Designing multi-agent architecture and generating Kite code... (this may take a minute)")
        agent = ai.create_agent(
            name="Generator",
            system_prompt="You generate code. Return ONLY raw Python code text, no markdown fencing, no explanation.",
            verbose=False
        )
        
        result = await agent.run(system_instructions)
        text = result.get("response", "").strip()
        
        # Robust LLM failure detection
        if not result.get("success", True):
            error_msg = result.get("error", "Unknown error")
            print(f"❌ Generation failed: {error_msg}")
            print("   Check your API key and LLM_PROVIDER in .env")
            sys.exit(1)
            
        if not text or text.lower().startswith("error") or "connection error" in text.lower():
            print(f"❌ Generation failed: {text or 'No response from LLM'}")
            print("   Check your API key and LLM_PROVIDER in .env")
            sys.exit(1)
            
        # Clean up formatting if it accidentally included markdown
        if text.startswith("```python"):
            text = text[9:]
        elif text.startswith("```"):
            text = text[3:]
        if text.endswith("```"):
            text = text[:-3]
        text = text.strip()

        # Final check — make sure output looks like Python
        if not any(kw in text for kw in ["import", "def ", "async ", "class "]):
            print(f"❌ Generated output doesn't look like valid Python code.")
            print(f"   LLM response: {text[:200]}")
            sys.exit(1)

        with open(out_path, "w", encoding="utf-8") as f:
            f.write(text)
        
        print(f"✅ Successfully generated Kite application to {out_path}")
        print(f"   Run: python {out_path}")

    asyncio.run(_generate())


# =============================================================================
# MAIN ENTRY POINT
# =============================================================================

def main():
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="kite",
        description="🪁 Kite Framework CLI - Build AI agents with ease",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=textwrap.dedent("""\
            Examples:
              kite init --type=agent --name=my_bot
              kite init --type=workflow --from-md=skill.md --name=scraper
              kite validate skills/my_skill.md
            
            Skill File Format:
              See docs/skill_format.md for the full skill.md specification.
        """)
    )
    
    subparsers = parser.add_subparsers(dest="command", help="Available commands")
    
    # kite init
    init_parser = subparsers.add_parser(
        "init",
        help="Scaffold a new Kite project"
    )
    init_parser.add_argument(
        "--type", "-t",
        choices=["agent", "workflow", "tool"],
        default="agent",
        help="Type of project to scaffold (default: agent)"
    )
    init_parser.add_argument(
        "--name", "-n",
        default=None,
        help="Project name (default: my_agent)"
    )
    
    # kite compile
    compile_parser = subparsers.add_parser(
        "compile",
        help="Compile a skill.md file into a multi-agent Python workflow using AI"
    )
    compile_parser.add_argument(
        "skill_file",
        help="Path to the skill .md file to compile"
    )
    compile_parser.add_argument(
        "--out", "-o",
        default="generated_app.py",
        help="Path to the output Python file (default: generated_app.py)"
    )
    
    # kite generate
    generate_parser = subparsers.add_parser(
        "generate",
        help="Generate a complete multi-agent Kite application from a natural language idea"
    )
    generate_parser.add_argument(
        "prompt",
        help="The natural language idea for your agent/workflow"
    )
    generate_parser.add_argument(
        "--out", "-o",
        default="generated_app.py",
        help="Path to the output Python file (default: generated_app.py)"
    )
    
    args = parser.parse_args()
    
    if args.command == "init":
        cmd_init(args)
    elif args.command == "compile":
        cmd_compile(args)
    elif args.command == "generate":
        cmd_generate(args)
    else:
        parser.print_help()
        sys.exit(1)


if __name__ == "__main__":
    main()
