from pathlib import Path
import sys
import markdown
from fastapi import FastAPI
from jinja2 import Environment, DictLoader
from markupsafe import Markup
from .image_service import ImageService, FileHandler


class MarkdownRenderer:
    def __init__(self, file_path: str = None, app: FastAPI=None):
        """
        Initialize the MarkdownRenderer with a Jinja2 environment and custom functions.
        """
        self.app = app
        self.image_service = ImageService(self.app)
        self.jinja_env = self._create_jinja_environment()
        self.file_path = file_path



    def _create_jinja_environment(self) -> Environment:
        """
        Create and configure the Jinja2 environment with custom functions.

        Returns:
            Environment: A configured Jinja2 environment.
        """
        env = Environment(loader=DictLoader({"base_template": "{{ content | safe }}"}))

        env.globals.update({
            "img_left_overlay": self.img_left_overlay,
            "box": self.box,
            "note": self.note,
            "warning": self.warning,
            "link_to": self.link_to,
            "slider": self.slider,
            "image": self.get_image,  # Add image handler function
        })
        return env

    def img_left_overlay(self, src: str) -> str:
        """Render an image with overlay."""
        return f'''
        <div class="img-left-overlay">
            <img src="{src}" alt="Overlay Image" loading="lazy">
            <div class="overlay-text">Overlay Text</div>
        </div>
        '''

    def box(self, title: str, content: str) -> str:
        """Render a box component."""
        return f'''
        <div class="box">
            <strong>{title}</strong>
            <p>{content}</p>
        </div>
        '''

    def note(self, content: str) -> str:
        """Render a note component."""
        return f'''
        <div class="note">
            <p>{content}</p>
        </div>
        '''

    def link_to(self, title: str, url: str) -> str:
        """Render a link component."""
        return f'''
        <a href="{url}" target="_blank" rel="noopener noreferrer">{title}</a>
        '''

    def warning(self, content: str) -> str:
        """Render a warning component."""
        return f'''
        <div class="warning">
            ⚠️ <p>{content}</p>
        </div>
        '''

    def slider(self, options: dict, images: list) -> str:
        """Render a slider component."""
        import uuid
        modal_id = uuid.uuid4().hex.upper()[0:6]


        html_content = []
        html_content.append('<div class="button-stack">')
        for i, val in enumerate(images):
            self.image_service = ImageService( self.app )
            modal_id_current = f"{modal_id}_{i}"
            modal_id_next = f"{modal_id}_{i + 1}" if i + 1 < len(images) else f"{modal_id}_0"

            category = FileHandler().get_category(self.file_path)

            thumbnal_img = self.image_service.image_tag(category = category, image_type = "thumbnails",filename = val,alt="A better description later on")
            modal_img = self.image_service.image_tag(category = category, image_type = "large",filename = val,alt="A better description later on")
            html_content.append(f"""
            <button onclick="openModal('modal{modal_id_current}')" class="stacked-button">
                {thumbnal_img}
            </button>
            <div class="modal" id="modal{modal_id_current}">
                <div class="modal-content">
                    <h2>Modal {i}</h2>
                    {modal_img}
                    
                    <div class="modal-buttons">
                        <button onclick="closeModal('modal{modal_id_current}')">Close</button>
                        <button class="next-btn" onclick="nextModal('modal{modal_id_current}', 'modal{modal_id_next}')">Next</button>
                    </div>
                </div>
            </div>
            """)
        html_content.append('</div>')
        return '\n'.join(html_content)

    def _get_category(self):
        if isinstance(self.file_path, str):
            this_path = Path(self.file_path)
            return this_path.parent.name

        return True


    def get_image(self, image_type: str, filename: str, alt: str = "", width: int = None, height: int = None,css_class:str=None) -> Markup:
        """
        Generate a dynamic HTML <img> tag for an image using ImageService's image_tag method.
        """
        valid_types = ['thumbnails', 'large', 'small', 'original']
        if image_type not in valid_types:
            sys.tracebacklimit = 0
            raise ValueError( f"Invalid image type: {image_type}. Must be one of {valid_types}" )

        tag = self.image_service.image_tag(
            category=self._get_category(),
            image_type=image_type,
            filename=filename,
            alt=alt,
            width=width,
            height=height,
            css_class=css_class
        )
        return Markup(tag)





    def render_markdown_with_jinja(self, markdown_content: str):
        """
        Convert Markdown to HTML and apply Jinja2 rendering for custom tags.

        Args:
            markdown_content (str): Raw Markdown content.

        Returns:
            tuple: Rendered HTML content and metadata as a dictionary.
        """

        md = markdown.Markdown(extensions=["extra", "nl2br", "meta"])
        intermediate_html = md.convert(markdown_content)
        metadata = {key: " ".join(value) for key, value in md.Meta.items()} if md.Meta else {}

        # Step 3: Pass the resulting HTML with Jinja2 custom tags through Jinja2
        template = self.jinja_env.get_template("base_template")
        final_html = template.render(content=intermediate_html)

        # Step 4: Re-render final_html in Jinja2 for embedded tags like {{ image(...) }}
        final_output = self.jinja_env.from_string(final_html).render()

        return final_output, metadata