"""
Template-based slide creation tools for PowerPoint MCP Server.
Handles template application, template management, and automated slide generation.
"""
from typing import Dict, List, Optional, Any
from mcp.server.fastmcp import FastMCP
import utils.template_utils as template_utils


def register_template_tools(app: FastMCP, presentations: Dict, get_current_presentation_id):
    """Register template-based tools with the FastMCP app"""
    
    @app.tool()
    def list_slide_templates() -> Dict:
        """List all available slide layout templates."""
        try:
            available_templates = template_utils.get_available_templates()
            usage_examples = template_utils.get_template_usage_examples()
            
            return {
                "available_templates": available_templates,
                "total_templates": len(available_templates),
                "usage_examples": usage_examples,
                "message": "Use apply_slide_template to apply templates to slides"
            }
        except Exception as e:
            return {
                "error": f"Failed to list templates: {str(e)}"
            }
    
    @app.tool()
    def apply_slide_template(
        slide_index: int,
        template_id: str,
        color_scheme: str = "modern_blue",
        content_mapping: Optional[Dict[str, str]] = None,
        image_paths: Optional[Dict[str, str]] = None,
        presentation_id: Optional[str] = None
    ) -> Dict:
        """
        Apply a slide layout template to an existing slide.
        
        Args:
            slide_index: Index of the slide to apply template to
            template_id: ID of the template to apply (e.g., 'title_slide', 'text_with_image')
            color_scheme: Color scheme to use ('modern_blue', 'corporate_gray', 'elegant_green', 'warm_red')
            content_mapping: Dictionary mapping element roles to custom content
            image_paths: Dictionary mapping image element roles to file paths
            presentation_id: Presentation ID (uses current if None)
        """
        pres_id = presentation_id if presentation_id is not None else get_current_presentation_id()
        
        if pres_id is None or pres_id not in presentations:
            return {
                "error": "No presentation is currently loaded or the specified ID is invalid"
            }
        
        pres = presentations[pres_id]
        
        if slide_index < 0 or slide_index >= len(pres.slides):
            return {
                "error": f"Invalid slide index: {slide_index}. Available slides: 0-{len(pres.slides) - 1}"
            }
        
        slide = pres.slides[slide_index]
        
        try:
            result = template_utils.apply_slide_template(
                slide, template_id, color_scheme, 
                content_mapping or {}, image_paths or {}
            )
            
            if result['success']:
                return {
                    "message": f"Applied template '{template_id}' to slide {slide_index}",
                    "slide_index": slide_index,
                    "template_applied": result
                }
            else:
                return {
                    "error": f"Failed to apply template: {result.get('error', 'Unknown error')}"
                }
                
        except Exception as e:
            return {
                "error": f"Failed to apply template: {str(e)}"
            }
    
    @app.tool()
    def create_slide_from_template(
        template_id: str,
        color_scheme: str = "modern_blue",
        content_mapping: Optional[Dict[str, str]] = None,
        image_paths: Optional[Dict[str, str]] = None,
        layout_index: int = 1,
        presentation_id: Optional[str] = None
    ) -> Dict:
        """
        Create a new slide using a layout template.
        
        Args:
            template_id: ID of the template to use (e.g., 'title_slide', 'text_with_image')
            color_scheme: Color scheme to use ('modern_blue', 'corporate_gray', 'elegant_green', 'warm_red')
            content_mapping: Dictionary mapping element roles to custom content
            image_paths: Dictionary mapping image element roles to file paths
            layout_index: PowerPoint layout index to use as base (default: 1)
            presentation_id: Presentation ID (uses current if None)
        """
        pres_id = presentation_id if presentation_id is not None else get_current_presentation_id()
        
        if pres_id is None or pres_id not in presentations:
            return {
                "error": "No presentation is currently loaded or the specified ID is invalid"
            }
        
        pres = presentations[pres_id]
        
        # Validate layout index
        if layout_index < 0 or layout_index >= len(pres.slide_layouts):
            return {
                "error": f"Invalid layout index: {layout_index}. Available layouts: 0-{len(pres.slide_layouts) - 1}"
            }
        
        try:
            # Add new slide
            layout = pres.slide_layouts[layout_index]
            slide = pres.slides.add_slide(layout)
            slide_index = len(pres.slides) - 1
            
            # Apply template
            result = template_utils.apply_slide_template(
                slide, template_id, color_scheme,
                content_mapping or {}, image_paths or {}
            )
            
            if result['success']:
                return {
                    "message": f"Created slide {slide_index} using template '{template_id}'",
                    "slide_index": slide_index,
                    "template_applied": result
                }
            else:
                return {
                    "error": f"Failed to apply template to new slide: {result.get('error', 'Unknown error')}"
                }
                
        except Exception as e:
            return {
                "error": f"Failed to create slide from template: {str(e)}"
            }
    
    @app.tool()
    def create_presentation_from_templates(
        template_sequence: List[Dict[str, Any]],
        color_scheme: str = "modern_blue",
        presentation_title: Optional[str] = None,
        presentation_id: Optional[str] = None
    ) -> Dict:
        """
        Create a complete presentation from a sequence of templates.
        
        Args:
            template_sequence: List of template configurations, each containing:
                - template_id: Template to use
                - content: Content mapping for the template
                - images: Image path mapping for the template
            color_scheme: Color scheme to apply to all slides
            presentation_title: Optional title for the presentation
            presentation_id: Presentation ID (uses current if None)
        
        Example template_sequence:
        [
            {
                "template_id": "title_slide",
                "content": {
                    "title": "My Presentation",
                    "subtitle": "Annual Report 2024",
                    "author": "John Doe"
                }
            },
            {
                "template_id": "text_with_image",
                "content": {
                    "title": "Key Results",
                    "content": "• Achievement 1\\n• Achievement 2"
                },
                "images": {
                    "supporting": "/path/to/image.jpg"
                }
            }
        ]
        """
        pres_id = presentation_id if presentation_id is not None else get_current_presentation_id()
        
        if pres_id is None or pres_id not in presentations:
            return {
                "error": "No presentation is currently loaded or the specified ID is invalid"
            }
        
        pres = presentations[pres_id]
        
        if not template_sequence:
            return {
                "error": "Template sequence cannot be empty"
            }
        
        try:
            # Set presentation title if provided
            if presentation_title:
                pres.core_properties.title = presentation_title
            
            # Create slides from template sequence
            result = template_utils.create_presentation_from_template_sequence(
                pres, template_sequence, color_scheme
            )
            
            if result['success']:
                return {
                    "message": f"Created presentation with {result['total_slides']} slides",
                    "presentation_id": pres_id,
                    "creation_result": result,
                    "total_slides": len(pres.slides)
                }
            else:
                return {
                    "warning": "Presentation created with some errors",
                    "presentation_id": pres_id,
                    "creation_result": result,
                    "total_slides": len(pres.slides)
                }
                
        except Exception as e:
            return {
                "error": f"Failed to create presentation from templates: {str(e)}"
            }
    
    @app.tool()
    def get_template_info(template_id: str) -> Dict:
        """
        Get detailed information about a specific template.
        
        Args:
            template_id: ID of the template to get information about
        """
        try:
            templates_data = template_utils.load_slide_templates()
            
            if template_id not in templates_data.get('templates', {}):
                available_templates = list(templates_data.get('templates', {}).keys())
                return {
                    "error": f"Template '{template_id}' not found",
                    "available_templates": available_templates
                }
            
            template = templates_data['templates'][template_id]
            
            # Extract element information
            elements_info = []
            for element in template.get('elements', []):
                element_info = {
                    "type": element.get('type'),
                    "role": element.get('role'),
                    "position": element.get('position'),
                    "placeholder_text": element.get('placeholder_text', ''),
                    "styling_options": list(element.get('styling', {}).keys())
                }
                elements_info.append(element_info)
            
            return {
                "template_id": template_id,
                "name": template.get('name'),
                "description": template.get('description'),
                "layout_type": template.get('layout_type'),
                "elements": elements_info,
                "element_count": len(elements_info),
                "has_background": 'background' in template,
                "background_type": template.get('background', {}).get('type'),
                "color_schemes": list(templates_data.get('color_schemes', {}).keys()),
                "usage_tip": f"Use create_slide_from_template with template_id='{template_id}' to create a slide with this layout"
            }
            
        except Exception as e:
            return {
                "error": f"Failed to get template info: {str(e)}"
            }
    
    @app.tool()
    def auto_generate_presentation(
        topic: str,
        slide_count: int = 5,
        presentation_type: str = "business",
        color_scheme: str = "modern_blue",
        include_charts: bool = True,
        include_images: bool = False,
        presentation_id: Optional[str] = None
    ) -> Dict:
        """
        Automatically generate a presentation based on topic and preferences.
        
        Args:
            topic: Main topic/theme for the presentation
            slide_count: Number of slides to generate (3-20)
            presentation_type: Type of presentation ('business', 'academic', 'creative')
            color_scheme: Color scheme to use
            include_charts: Whether to include chart slides
            include_images: Whether to include image placeholders
            presentation_id: Presentation ID (uses current if None)
        """
        pres_id = presentation_id if presentation_id is not None else get_current_presentation_id()
        
        if pres_id is None or pres_id not in presentations:
            return {
                "error": "No presentation is currently loaded or the specified ID is invalid"
            }
        
        if slide_count < 3 or slide_count > 20:
            return {
                "error": "Slide count must be between 3 and 20"
            }
        
        try:
            # Define presentation structures based on type
            if presentation_type == "business":
                base_templates = [
                    ("title_slide", {"title": f"{topic}", "subtitle": "Executive Presentation", "author": "Business Team"}),
                    ("agenda_slide", {"agenda_items": "1. Executive Summary\n\n2. Current Situation\n\n3. Analysis & Insights\n\n4. Recommendations\n\n5. Next Steps"}),
                    ("key_metrics_dashboard", {"title": "Key Performance Indicators"}),
                    ("text_with_image", {"title": "Current Situation", "content": f"Overview of {topic}:\n• Current status\n• Key challenges\n• Market position"}),
                    ("two_column_text", {"title": "Analysis", "content_left": "Strengths:\n• Advantage 1\n• Advantage 2\n• Advantage 3", "content_right": "Opportunities:\n• Opportunity 1\n• Opportunity 2\n• Opportunity 3"}),
                ]
                if include_charts:
                    base_templates.append(("chart_comparison", {"title": "Performance Comparison"}))
                base_templates.append(("thank_you_slide", {"contact": "Thank you for your attention\nQuestions & Discussion"}))
            
            elif presentation_type == "academic":
                base_templates = [
                    ("title_slide", {"title": f"Research on {topic}", "subtitle": "Academic Study", "author": "Research Team"}),
                    ("agenda_slide", {"agenda_items": "1. Introduction\n\n2. Literature Review\n\n3. Methodology\n\n4. Results\n\n5. Conclusions"}),
                    ("text_with_image", {"title": "Introduction", "content": f"Research focus on {topic}:\n• Background\n• Problem statement\n• Research questions"}),
                    ("two_column_text", {"title": "Methodology", "content_left": "Approach:\n• Method 1\n• Method 2\n• Method 3", "content_right": "Data Sources:\n• Source 1\n• Source 2\n• Source 3"}),
                    ("data_table_slide", {"title": "Results Summary"}),
                ]
                if include_charts:
                    base_templates.append(("chart_comparison", {"title": "Data Analysis"}))
                base_templates.append(("thank_you_slide", {"contact": "Questions & Discussion\nContact: research@university.edu"}))
            
            else:  # creative
                base_templates = [
                    ("title_slide", {"title": f"Creative Vision: {topic}", "subtitle": "Innovative Concepts", "author": "Creative Team"}),
                    ("full_image_slide", {"overlay_title": f"Exploring {topic}", "overlay_subtitle": "Creative possibilities"}),
                    ("three_column_layout", {"title": "Creative Concepts"}),
                    ("quote_testimonial", {"quote_text": f"Innovation in {topic} requires thinking beyond conventional boundaries", "attribution": "— Creative Director"}),
                    ("process_flow", {"title": "Creative Process"}),
                ]
                if include_charts:
                    base_templates.append(("key_metrics_dashboard", {"title": "Impact Metrics"}))
                base_templates.append(("thank_you_slide", {"contact": "Let's create something amazing together\ncreative@studio.com"}))
            
            # Adjust templates to match requested slide count
            template_sequence = []
            templates_to_use = base_templates[:slide_count]
            
            # If we need more slides, add content slides
            while len(templates_to_use) < slide_count:
                if include_images:
                    templates_to_use.insert(-1, ("text_with_image", {"title": f"{topic} - Additional Topic", "content": "• Key point\n• Supporting detail\n• Additional insight"}))
                else:
                    templates_to_use.insert(-1, ("two_column_text", {"title": f"{topic} - Analysis", "content_left": "Key Points:\n• Point 1\n• Point 2", "content_right": "Details:\n• Detail 1\n• Detail 2"}))
            
            # Convert to proper template sequence format
            for i, (template_id, content) in enumerate(templates_to_use):
                template_config = {
                    "template_id": template_id,
                    "content": content
                }
                template_sequence.append(template_config)
            
            # Create the presentation
            result = template_utils.create_presentation_from_template_sequence(
                presentations[pres_id], template_sequence, color_scheme
            )
            
            return {
                "message": f"Auto-generated {slide_count}-slide presentation on '{topic}'",
                "topic": topic,
                "presentation_type": presentation_type,
                "color_scheme": color_scheme,
                "slide_count": slide_count,
                "generation_result": result,
                "templates_used": [t[0] for t in templates_to_use]
            }
            
        except Exception as e:
            return {
                "error": f"Failed to auto-generate presentation: {str(e)}"
            }