"""
MCP component creation and operations logic
"""

from typing import Dict, Any, Optional, List
try:
    from ..templates import get_template, get_pattern, get_solution, PITFALLS_AND_SOLUTIONS
except ImportError:
    # Handle direct execution
    from templates import get_template, get_pattern, get_solution, PITFALLS_AND_SOLUTIONS


def create_component(
    component_type: str,
    name: str,
    description: str,
    parameters: Optional[Dict[str, str]] = None,
    return_type: str = "str"
) -> str:
    """
    Create boilerplate code for a new MCP component
    
    Args:
        component_type: Type of component (tool, resource, prompt)
        name: Name of the component
        description: Description of what the component does
        parameters: Dictionary of parameter names to types (for tools/prompts)
        return_type: Return type for the component
        
    Returns:
        Generated code for the MCP component
    """
    if component_type not in ["tool", "resource", "prompt"]:
        return f"Error: Invalid component type '{component_type}'. Must be 'tool', 'resource', or 'prompt'."
    
    # Prepare template variables
    template_vars = {
        "tool_name": name,
        "resource_name": name,
        "prompt_name": name,
        "description": description,
        "return_type": return_type,
        "implementation": "# TODO: Implement component logic here"
    }
    
    # Handle parameters
    if parameters:
        param_list = []
        args_desc = []
        
        for param_name, param_type in parameters.items():
            param_list.append(f"{param_name}: {param_type}")
            args_desc.append(f"        {param_name}: {param_type} parameter")
        
        template_vars["parameters"] = ", ".join(param_list)
        template_vars["args_description"] = "\n".join(args_desc)
    else:
        template_vars["parameters"] = ""
        template_vars["args_description"] = "        No parameters"
    
    # Return description
    template_vars["return_description"] = f"Returns a {return_type} with the component result"
    
    # Generate the code
    try:
        code = get_template(component_type, **template_vars)
        
        # Add usage example and notes
        example_code = generate_usage_example(component_type, name, parameters or {})
        
        return f"""
{code}

# Usage Example:
{example_code}

# Notes:
# - This component follows Storm Logger MCP patterns
# - Add proper error handling and validation
# - Consider adding logging for debugging
# - Update documentation as needed
"""
    except Exception as e:
        return f"Error generating component: {str(e)}"


def generate_usage_example(component_type: str, name: str, parameters: Dict[str, str]) -> str:
    """
    Generate usage example for the component
    
    Args:
        component_type: Type of component
        name: Name of the component
        parameters: Parameters dictionary
        
    Returns:
        Usage example code
    """
    if component_type == "tool":
        if parameters:
            param_examples = []
            for param_name, param_type in parameters.items():
                if param_type == "str":
                    param_examples.append(f'{param_name}="example_value"')
                elif param_type == "int":
                    param_examples.append(f'{param_name}=42')
                elif param_type == "bool":
                    param_examples.append(f'{param_name}=True')
                else:
                    param_examples.append(f'{param_name}=example_value')
            
            return f"""
# Using the tool via MCP client:
result = await client.call_tool("{name}", {{{", ".join(param_examples)}}})
"""
        else:
            return f"""
# Using the tool via MCP client:
result = await client.call_tool("{name}")
"""
    
    elif component_type == "resource":
        return f"""
# Reading the resource via MCP client:
resource_content = await client.read_resource("storm-logger://{name}")
"""
    
    elif component_type == "prompt":
        if parameters:
            param_examples = []
            for param_name, param_type in parameters.items():
                if param_type == "str":
                    param_examples.append(f'{param_name}="example_value"')
                else:
                    param_examples.append(f'{param_name}=example_value')
            
            return f"""
# Using the prompt via MCP client:
prompt_text = await client.get_prompt("{name}", {{{", ".join(param_examples)}}})
"""
        else:
            return f"""
# Using the prompt via MCP client:
prompt_text = await client.get_prompt("{name}")
"""
    
    return "# Usage example not available"


def get_component_templates() -> Dict[str, str]:
    """
    Get all available component templates
    
    Returns:
        Dictionary of component templates
    """
    return {
        "tool": get_template("tool"),
        "resource": get_template("resource"),
        "prompt": get_template("prompt"),
        "server": get_template("server"),
        "unit_test": get_template("unit_test"),
        "integration_test": get_template("integration_test")
    }


def get_common_patterns() -> Dict[str, str]:
    """
    Get common MCP patterns
    
    Returns:
        Dictionary of common patterns
    """
    return {
        "tool_method": get_pattern("tool_method"),
        "resource_method": get_pattern("resource_method"),
        "prompt_method": get_pattern("prompt_method"),
        "error_handling": get_pattern("error_handling"),
        "async_pattern": get_pattern("async_pattern"),
        "mock_pattern": get_pattern("mock_pattern")
    }


def get_pitfall_solutions() -> Dict[str, Any]:
    """
    Get solutions for common pitfalls
    
    Returns:
        Dictionary of pitfall solutions
    """
    return PITFALLS_AND_SOLUTIONS


def validate_component_spec(component_type: str, name: str, description: str, parameters: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
    """
    Validate component specification
    
    Args:
        component_type: Type of component
        name: Name of the component
        description: Description of the component
        parameters: Parameters dictionary
        
    Returns:
        Validation result
    """
    validation = {
        "valid": True,
        "errors": [],
        "warnings": [],
        "suggestions": []
    }
    
    # Validate component type
    if component_type not in ["tool", "resource", "prompt"]:
        validation["valid"] = False
        validation["errors"].append(f"Invalid component type '{component_type}'. Must be 'tool', 'resource', or 'prompt'.")
    
    # Validate name
    if not name or not name.strip():
        validation["valid"] = False
        validation["errors"].append("Component name is required.")
    elif not name.replace("_", "").isalnum():
        validation["warnings"].append("Component name should only contain alphanumeric characters and underscores.")
    
    # Validate description
    if not description or not description.strip():
        validation["valid"] = False
        validation["errors"].append("Component description is required.")
    elif len(description) < 10:
        validation["warnings"].append("Component description should be more descriptive (at least 10 characters).")
    
    # Validate parameters
    if parameters:
        for param_name, param_type in parameters.items():
            if not param_name.replace("_", "").isalnum():
                validation["warnings"].append(f"Parameter name '{param_name}' should only contain alphanumeric characters and underscores.")
            
            if param_type not in ["str", "int", "bool", "float", "List[str]", "Dict[str, Any]", "Optional[str]"]:
                validation["warnings"].append(f"Parameter type '{param_type}' might not be a standard Python type.")
    
    # Add suggestions
    if component_type == "tool":
        validation["suggestions"].append("Consider adding error handling and input validation.")
        validation["suggestions"].append("Add logging for debugging purposes.")
    elif component_type == "resource":
        validation["suggestions"].append("Consider caching resource data for performance.")
        validation["suggestions"].append("Add proper error handling for resource loading.")
    elif component_type == "prompt":
        validation["suggestions"].append("Make prompt templates flexible and reusable.")
        validation["suggestions"].append("Consider adding context validation.")
    
    return validation


def generate_test_template(component_type: str, name: str, parameters: Optional[Dict[str, str]] = None) -> str:
    """
    Generate test template for the component
    
    Args:
        component_type: Type of component
        name: Name of the component
        parameters: Parameters dictionary
        
    Returns:
        Test template code
    """
    test_class_name = f"Test{name.replace('_', '').title()}"
    
    if component_type == "tool":
        method_name = "call_tool"
        method_args = f'"{name}"'
        if parameters:
            param_pairs = [f'"{k}": "test_value"' for k in parameters.keys()]
            method_args += f", {{{', '.join(param_pairs)}}}"
        expected_response = '"test response"'
    elif component_type == "resource":
        method_name = "read_resource"
        method_args = f'"storm-logger://{name}"'
        expected_response = '"test resource data"'
    elif component_type == "prompt":
        method_name = "get_prompt"
        method_args = f'"{name}"'
        if parameters:
            param_pairs = [f'"{k}": "test_value"' for k in parameters.keys()]
            method_args += f", {{{', '.join(param_pairs)}}}"
        expected_response = '"test prompt"'
    else:
        return "# Test template not available for this component type"
    
    return get_template("unit_test",
        component_name=name,
        test_class_name=test_class_name,
        component_type=component_type,
        test_name=f"{name}_basic_functionality",
        test_description=f"basic {component_type} functionality",
        method_name=method_name,
        method_args=method_args,
        expected_response=expected_response,
        assertions=f'assert result == {expected_response}'
    )


def get_component_best_practices(component_type: str) -> List[str]:
    """
    Get best practices for component type
    
    Args:
        component_type: Type of component
        
    Returns:
        List of best practices
    """
    common_practices = [
        "Follow Storm Logger naming conventions",
        "Add comprehensive error handling",
        "Include proper logging for debugging",
        "Write clear and detailed docstrings",
        "Add input validation and sanitization",
        "Consider performance implications",
        "Write comprehensive tests",
        "Handle edge cases gracefully"
    ]
    
    if component_type == "tool":
        return common_practices + [
            "Validate all input parameters",
            "Return structured JSON responses",
            "Add timeout handling for long operations",
            "Consider async operations for I/O",
            "Add progress tracking for long operations"
        ]
    elif component_type == "resource":
        return common_practices + [
            "Cache resource data when appropriate",
            "Handle resource not found scenarios",
            "Consider resource versioning",
            "Add resource metadata",
            "Handle large resources efficiently"
        ]
    elif component_type == "prompt":
        return common_practices + [
            "Make prompts flexible and reusable",
            "Add context validation",
            "Consider prompt versioning",
            "Handle missing parameters gracefully",
            "Add prompt templates for common cases"
        ]
    
    return common_practices