"""
TestDrive JSUI Rendering Engine Plugin

Independent JavaScript UI rendering engine for Markitect edit mode.
Designed for standalone development and testing of JavaScript components.
"""

from pathlib import Path
from typing import Dict, List, Optional
import json

from .base import PluginMetadata, PluginType
from .rendering import RenderingEnginePlugin, RenderingConfig


class TestDriveJSUIEngine(RenderingEnginePlugin):
    """TestDrive JavaScript UI rendering engine."""

    def __init__(self):
        super().__init__()
        self._metadata = PluginMetadata(
            name="testdrive-jsui",
            version="1.0.0",
            description="Independent JavaScript UI engine for markdown editing",
            author="Markitect Team",
            plugin_type=PluginType.RENDERING
        )

    @property
    def metadata(self) -> PluginMetadata:
        """Return plugin metadata."""
        return self._metadata

    def get_supported_modes(self) -> List[str]:
        """Support edit and view modes."""
        return ["edit", "view"]

    def get_plugin_source_dir(self) -> Path:
        """
        Return the source directory for this plugin.
        This allows the plugin to declare its own location.
        """
        # Plugin is located in capabilities/testdrive-jsui/
        return Path(__file__).parent.parent.parent / "capabilities" / "testdrive-jsui"

    def get_asset_paths(self) -> Dict[str, Path]:
        """
        Return paths to asset directories relative to plugin source.
        This allows flexible asset organization within the plugin.
        """
        base = self.get_plugin_source_dir()
        return {
            'js': base / 'js',
            'css': base / 'static' / 'css',
            'images': base / 'static' / 'images',
            'templates': base / 'static' / 'templates',
        }

    def get_required_assets(self) -> Dict[str, List[str]]:
        """
        Define required JavaScript, CSS, and other assets.
        All paths are relative to the plugin source directory.
        """
        return {
            "js": [
                "js/core/debug-system.js",
                "js/core/section-manager.js",
                "js/components/debug-panel.js",
                "js/components/dom-renderer.js",
                "js/controls/control-base.js",
                "js/controls/contents-control.js",
                "js/controls/status-control.js",
                "js/controls/debug-control.js",
                "js/controls/edit-control.js",
                "js/config-loader.js",
                "js/main-updated.js"
            ],
            "css": [
                "static/css/editor.css",
                "static/css/controls.css",
                "static/css/themes/github.css"
            ],
            "images": [
                "static/images/icons/edit.png",
                "static/images/icons/save.png",
                "static/images/icons/reset.png"
            ],
            "external": [
                "https://cdn.jsdelivr.net/npm/marked/marked.min.js"
            ]
        }

    def get_template_path(self) -> Optional[Path]:
        """Return path to the HTML template."""
        # Template is in the plugin's static/templates directory
        template_path = self.get_asset_paths()['templates'] / "index.html"

        if template_path.exists():
            return template_path

        raise FileNotFoundError(
            f"Template not found at {template_path}. "
            f"Ensure testdrive-jsui is properly installed in capabilities/"
        )

    def render_document(self,
                       content: str,
                       mode: str,
                       config: RenderingConfig) -> str:
        """
        Render markdown content using TestDrive JSUI.

        Args:
            content: Markdown content to render
            mode: Rendering mode ('edit' or 'view')
            config: Rendering configuration

        Returns:
            Complete HTML document
        """
        if not self.validate_mode(mode):
            raise ValueError(f"Mode '{mode}' not supported by TestDrive JSUI engine")

        # Get template
        template_path = self.get_template_path()
        if not template_path or not template_path.exists():
            raise FileNotFoundError(f"Template not found: {template_path}")

        # Load template content
        with open(template_path, 'r', encoding='utf-8') as f:
            template_content = f.read()

        # Generate asset URLs
        assets = self.get_required_assets()
        js_scripts = []
        css_links = []

        # External dependencies
        for external_url in assets.get("external", []):
            js_scripts.append(f'<script src="{external_url}"></script>')

        # Plugin assets
        for js_file in assets.get("js", []):
            url = config.get_asset_url(self.metadata.name, js_file)
            js_scripts.append(f'<script src="{url}"></script>')

        for css_file in assets.get("css", []):
            url = config.get_asset_url(self.metadata.name, css_file)
            css_links.append(f'<link rel="stylesheet" href="{url}">')

        # Generate configuration JSON for JavaScript
        js_config = {
            "markdownContent": content,
            "markdownContentWithDogtag": content,  # Could add dogtag here
            "dogtagContent": "",
            "mode": mode,
            "theme": "github",
            "keyboardShortcuts": True,
            "autosave": False,
            "sections": True,
            "originalFilename": "document",
            "base64References": {},
            "version": f"Markitect {self.metadata.version}",
            "repoName": "Markitect"
        }

        # Basic fallback content rendering (simple markdown to HTML)
        fallback_html = self._render_markdown_fallback(content)

        # Replace template placeholders using safe substitution
        html_content = template_content
        html_content = html_content.replace("{title}", "TestDrive JSUI Document")
        html_content = html_content.replace("{version}", f"Markitect {self.metadata.version}")
        html_content = html_content.replace("{mode_class}", f"markitect-{mode}-mode")
        html_content = html_content.replace("{css_content}", "\n".join(css_links))
        html_content = html_content.replace("{js_scripts}", "\n".join(js_scripts))
        html_content = html_content.replace("{config_json}", json.dumps(js_config, indent=2))
        html_content = html_content.replace("{fallback_content}", fallback_html)

        return html_content

    def _render_markdown_fallback(self, content: str) -> str:
        """
        Render basic markdown to HTML for fallback content.

        Args:
            content: Markdown content

        Returns:
            Basic HTML rendering
        """
        import re

        # Very basic markdown to HTML conversion for fallback
        html = content

        # Headers
        html = re.sub(r'^# (.+)$', r'<h1>\1</h1>', html, flags=re.MULTILINE)
        html = re.sub(r'^## (.+)$', r'<h2>\1</h2>', html, flags=re.MULTILINE)
        html = re.sub(r'^### (.+)$', r'<h3>\1</h3>', html, flags=re.MULTILINE)

        # Paragraphs
        html = re.sub(r'\n\n', '</p><p>', html)
        html = re.sub(r'\n', '<br>', html)

        # Wrap in paragraph tags
        if html.strip() and not html.startswith('<'):
            html = f'<p>{html}</p>'

        return html

    def get_development_config(self, source_dir: Path) -> RenderingConfig:
        """
        Get development configuration for standalone testing.

        Args:
            source_dir: Path to testdrive-jsui source directory

        Returns:
            Development rendering configuration
        """
        return RenderingConfig(
            asset_base_url=".",  # Serve from current directory in dev
            development_mode=True,
            plugin_source_dirs={self.metadata.name: source_dir}
        )

    def create_standalone_test_document(self,
                                      test_content: str,
                                      output_path: Path) -> None:
        """
        Create a standalone HTML document for testing.

        Args:
            test_content: Markdown content to test with
            output_path: Where to write the test HTML file
        """
        config = self.get_development_config(output_path.parent)
        html_content = self.render_document(test_content, "edit", config)

        output_path.write_text(html_content, encoding='utf-8')
        print(f"✅ Created standalone test document: {output_path}")