"""
Clean Document Manager - Simplified version with only clean editor support
"""
import json
import re
from pathlib import Path
from typing import Dict, Any, Optional


class CleanDocumentManager:
    """
    Simplified document manager that only supports the clean editor implementation.
    All legacy code has been removed for clarity and maintainability.
    """

    def __init__(self, db_manager=None):
        self.db_manager = db_manager

    def store_document(self, file_path: str, content: str, ast: list = None, front_matter: dict = None):
        """Store a document in the database."""
        if self.db_manager:
            from pathlib import Path
            filename = Path(file_path).name
            return self.db_manager.store_markdown_file(filename, content)

    def get_file(self, file_path: str) -> Dict[str, Any]:
        """
        Retrieve a markdown file from the database.

        Args:
            file_path: Path to the markdown file to retrieve

        Returns:
            Dictionary containing file content and metadata

        Raises:
            FileNotFoundError: If file is not found in database
        """
        if not self.db_manager:
            raise ValueError("Database manager not initialized")

        # Get file from database
        file_data = self.db_manager.get_markdown_file(file_path)

        if file_data is None:
            raise FileNotFoundError(f"File '{file_path}' not found in database")

        return {
            'content': file_data.get('content', ''),
            'metadata': {
                'filename': file_data.get('filename', file_path),
                'front_matter': file_data.get('front_matter'),
                'size': len(file_data.get('content', '')),
                'modified': file_data.get('modified')
            }
        }

    def render_file(self, input_file: str, output_file: str, template: str = None, css: str = None,
                   edit_mode: bool = False, insert_mode: bool = False, editor_theme: str = 'github', keyboard_shortcuts: bool = True, nodogtag: bool = False,
                   image_max_width: str = '12cm', image_max_height: str = '20cm') -> Dict[str, Any]:
        """
        Render a markdown file to HTML with optional clean editing capabilities.
        """
        input_path = Path(input_file)
        output_path = Path(output_file)

        if not input_path.exists():
            raise FileNotFoundError(f"Input file not found: {input_file}")

        # Read markdown content
        raw_markdown_content = input_path.read_text(encoding='utf-8')

        # Process base64 images - relocate payloads to document end
        markdown_content, base64_references = self._process_base64_images(raw_markdown_content)

        # Extract title from markdown (first h1 heading)
        title = self._extract_title_from_markdown(markdown_content)

        # Get original filename without extension
        original_filename = input_path.stem

        # Get version information
        version_info = self._get_version_info()

        # Generate HTML content
        html_content = self._generate_html_template(
            markdown_content=markdown_content,
            title=title,
            css=css,
            template=template,
            edit_mode=edit_mode,
            insert_mode=insert_mode,
            editor_theme=editor_theme,
            keyboard_shortcuts=keyboard_shortcuts,
            original_filename=original_filename,
            version_info=version_info,
            nodogtag=nodogtag,
            image_max_width=image_max_width,
            image_max_height=image_max_height,
            base64_references=base64_references
        )

        # Write HTML file
        output_path.parent.mkdir(parents=True, exist_ok=True)
        output_path.write_text(html_content, encoding='utf-8')

        return {
            'success': True,
            'input_file': str(input_path),
            'output_file': str(output_path),
            'edit_mode': edit_mode,
            'editor_theme': editor_theme
        }

    def _extract_title_from_markdown(self, markdown_content: str) -> str:
        """Extract title from first h1 heading in markdown."""
        match = re.search(r'^#\s+(.+)', markdown_content, re.MULTILINE)
        if match:
            return match.group(1).strip()
        return "Markdown Document"

    def _process_base64_images(self, markdown_content: str) -> tuple:
        """
        Process base64 encoded images in markdown content.

        - Extracts base64 image data URLs
        - Replaces them with reference links
        - Returns processed content and reference mapping

        Returns:
            tuple: (processed_markdown, base64_references_dict)
        """
        import re
        import uuid

        # Pattern to match base64 image data URLs
        base64_pattern = r'!\[([^\]]*)\]\(data:image/([^;]+);base64,([^)]+)\)'

        base64_references = {}
        reference_definitions = []
        processed_content = markdown_content

        # Find all base64 images
        matches = list(re.finditer(base64_pattern, markdown_content))

        for i, match in enumerate(matches):
            alt_text = match.group(1)
            image_type = match.group(2)  # png, jpeg, svg+xml, etc.
            base64_data = match.group(3)

            # Generate a unique reference ID
            ref_id = f"base64-image-{i+1}"

            # Store the mapping
            base64_references[ref_id] = {
                'alt': alt_text,
                'type': image_type,
                'data': base64_data,
                'full_data_url': f"data:image/{image_type};base64,{base64_data}"
            }

            # Replace the inline base64 with reference
            original_match = match.group(0)
            reference_link = f"![{alt_text}][{ref_id}]"
            processed_content = processed_content.replace(original_match, reference_link, 1)

            # Create reference definition for the end of document
            reference_definitions.append(f"[{ref_id}]: data:image/{image_type};base64,{base64_data}")

        # Add reference definitions to the end of the document if any base64 images were found
        if reference_definitions:
            # Ensure there's a blank line before the references
            if not processed_content.endswith('\n\n'):
                if processed_content.endswith('\n'):
                    processed_content += '\n'
                else:
                    processed_content += '\n\n'

            # Add a comment to indicate the base64 reference section
            processed_content += "<!-- Base64 Image References -->\n"
            processed_content += '\n'.join(reference_definitions) + '\n'

        return processed_content, base64_references

    def _get_version_info(self) -> dict:
        """Get repository name and version information."""
        from .__version__ import get_version

        return {
            'repo_name': 'Markitect',
            'version': get_version(),
            'git_info': '',
        }

    def _get_template_css(self, template: str = None, image_max_width: str = '12cm', image_max_height: str = '20cm') -> str:
        """Generate layered theme CSS styles."""
        # Import layered theme functions
        from markitect.plugins.builtin.markdown_commands import (
            parse_theme_string, combine_theme_properties, TEMPLATE_STYLES
        )

        # Handle layered themes or fall back to legacy
        if template and ',' in template:
            # New layered theme system
            theme_list = parse_theme_string(template)
            combined_props = combine_theme_properties(theme_list)
            return self._generate_layered_css(combined_props, image_max_width, image_max_height)
        else:
            # Legacy single theme or fallback
            if not template or template not in TEMPLATE_STYLES:
                # Use default layered themes or the specified theme
                theme_list = parse_theme_string(template or 'basic')
                combined_props = combine_theme_properties(theme_list)
                return self._generate_layered_css(combined_props, image_max_width, image_max_height)
            else:
                # Legacy theme - convert to layered
                theme_list = parse_theme_string(template)
                combined_props = combine_theme_properties(theme_list)
                return self._generate_layered_css(combined_props, image_max_width, image_max_height)

    def _generate_layered_css(self, properties: dict, image_max_width: str = '12cm', image_max_height: str = '20cm') -> str:
        """Generate CSS from combined theme properties."""

        # Set defaults for missing properties (properties override defaults)
        defaults = {
            'body_background': '#ffffff',
            'body_color': '#333333',
            'font_family': '-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif',
            'max_width': '800px',
            'heading_color': '#333333',  # Use same as body color by default
            'heading_style': 'simple',
            'text_align': 'left',
            'code_background': '#f6f8fa',
            'code_color': '#333333',
            'border_color': '#d0d7de',
            'blockquote_border': '#dfe2e5',
            'blockquote_color': '#6a737d',
            'table_border': '#d0d7de',
            'table_header_bg': '#f6f8fa',
            'accent_color': None,
            'secondary_color': None
        }

        # Merge defaults first, then override with theme properties
        props = {**defaults, **properties}

        # Base CSS
        base_css = f"""
            body {{
                font-family: {props['font_family']};
                max-width: {props['max_width']};
                margin: 0 auto;
                padding: 2rem;
                line-height: 1.6;
                color: {props['body_color']};
                background-color: {props['body_background']};
            }}
            #markdown-content {{
                min-height: 200px;
            }}"""

        # Heading styles
        heading_font_style = ""
        if 'heading_font_family' in props and props['heading_font_family']:
            heading_font_style = f"font-family: {props['heading_font_family']};"

        heading_css = ""
        if props['heading_style'] == 'underlined':
            heading_css = f"""
            h1, h2, h3, h4, h5, h6 {{
                color: {props['heading_color']};
                {heading_font_style}
                border-bottom: 1px solid {props['border_color']};
                padding-bottom: 0.3em;
            }}"""
        elif props['heading_style'] == 'centered':
            heading_css = f"""
            h1, h2, h3, h4, h5, h6 {{
                color: {props['heading_color']};
                {heading_font_style}
                margin-top: 2rem;
                margin-bottom: 1rem;
            }}
            h1 {{
                text-align: center;
                font-size: 2.2em;
                border-bottom: 2px solid {props['heading_color']};
                padding-bottom: 0.5rem;
            }}"""
        else:  # simple
            heading_css = f"""
            h1, h2, h3, h4, h5, h6 {{
                color: {props['heading_color']};
                {heading_font_style}
            }}"""

        # Text alignment
        text_css = ""
        if props['text_align'] == 'justify':
            text_css = """
            p {
                text-align: justify;
                margin-bottom: 1.2rem;
            }"""

        # Element styling
        element_css = f"""
            pre {{
                background-color: {props['code_background']};
                color: {props['code_color']};
                padding: 1rem;
                border-radius: 6px;
                overflow-x: auto;
                border: 1px solid {props['border_color']};
            }}
            code {{
                background-color: {props['code_background']};
                color: {props['code_color']};
                padding: 0.2em 0.4em;
                border-radius: 3px;
                font-size: 0.9em;
            }}
            pre code {{
                background: none;
                padding: 0;
            }}
            blockquote {{
                border-left: 4px solid {props['blockquote_border']};
                margin: 0;
                padding-left: 1rem;
                color: {props['blockquote_color']};
            }}
            table {{
                font-size: 0.85em;
                border-collapse: collapse;
                margin: 1rem 0;
                width: 100%;
                border: 1px solid {props['table_border']};
            }}
            th, td {{
                font-size: inherit;
                border: 1px solid {props['table_border']};
                padding: 0.5rem;
                text-align: left;
            }}
            th {{
                background-color: {props['table_header_bg']};
                font-weight: 600;
            }}"""

        # Link styling
        link_css = ""
        if props.get('link_color'):
            link_css = f"""
            a {{
                color: {props['link_color']};
                text-decoration: underline;
            }}"""
            if props.get('link_hover_color'):
                link_css += f"""
            a:hover {{
                color: {props['link_hover_color']};
            }}"""
            else:
                link_css += """
            a:hover {
                opacity: 0.8;
            }"""

        # Branding accents (if specified and no link_color already set)
        accent_css = ""
        if props.get('accent_color') and not props.get('link_color'):
            accent_css = f"""
            a {{
                color: {props['accent_color']};
            }}
            a:hover {{
                opacity: 0.8;
            }}"""

        # UI theme styling for editor interface elements
        ui_css = ""
        if props.get('editor_panel_bg'):
            ui_css = f"""
            .markitect-edit-mode .ui-edit-floater-panel {{
                background: {props['editor_panel_bg']};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                box-shadow: 0 4px 12px {props.get('editor_shadow', 'rgba(0,0,0,0.1)')};
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-edit-mode .ui-edit-floater-header {{
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-edit-mode .ui-edit-floater-header h3 {{
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-edit-mode .ui-edit-inline-panel {{
                background: {props['editor_panel_bg']};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                box-shadow: 0 2px 8px {props.get('editor_shadow', 'rgba(0,0,0,0.1)')};
                color: {props.get('editor_text_color', '#212529')};
                border-radius: 8px;
                padding: 12px;
                margin: 8px 0;
            }}
            .markitect-edit-mode .ui-edit-button {{
                background: {props.get('editor_button_bg', '#ffffff')};
                color: {props.get('editor_text_color', '#212529')};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                padding: 8px 12px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 12px;
                min-width: 70px;
                font-weight: 500;
                transition: all 0.2s;
            }}
            .markitect-edit-mode .ui-edit-button:hover {{
                background: {props.get('editor_button_hover', '#e9ecef')};
            }}
            .markitect-edit-mode .ui-edit-button:active,
            .markitect-edit-mode .ui-edit-button.active {{
                background: {props.get('editor_button_active', '#dee2e6')};
            }}
            .markitect-edit-mode .ui-edit-button-accept {{
                background: {props.get('editor_accept_bg', '#4caf50')};
                color: white;
            }}
            .markitect-edit-mode .ui-edit-button-accept:hover {{
                background: {props.get('editor_accept_hover', '#388e3c')};
            }}
            .markitect-edit-mode .ui-edit-button-cancel {{
                background: {props.get('editor_cancel_bg', '#f44336')};
                color: white;
            }}
            .markitect-edit-mode .ui-edit-button-cancel:hover {{
                background: {props.get('editor_cancel_hover', '#d32f2f')};
            }}
            .markitect-edit-mode .ui-edit-button-reset {{
                background: {props.get('editor_reset_bg', '#ff9800')};
                color: white;
            }}
            .markitect-edit-mode .ui-edit-button-reset:hover {{
                background: {props.get('editor_reset_hover', '#f57c00')};
            }}
            .markitect-edit-mode .ui-edit-button-secondary {{
                background: {props.get('editor_secondary_bg', '#6c757d')};
                color: white;
            }}
            .markitect-edit-mode .ui-edit-button-secondary:hover {{
                background: {props.get('editor_secondary_hover', '#545b62')};
            }}
            .markitect-edit-mode .ui-edit-section-frame {{
                border: 2px solid {props.get('editor_focus_color', props.get('editor_panel_border', '#dee2e6'))};
                box-shadow: 0 0 0 3px {props.get('editor_focus_color', props.get('editor_panel_border', '#dee2e6'))}33;
            }}
            .markitect-edit-mode .ui-edit-textarea {{
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                color: {props.get('editor_text_color', '#212529')};
                background: {props.get('editor_button_bg', '#ffffff')};
            }}
            .markitect-edit-mode .ui-edit-textarea:focus {{
                border-color: {props.get('editor_focus_color', props.get('editor_panel_border', '#dee2e6'))};
                box-shadow: 0 0 0 2px {props.get('editor_focus_color', props.get('editor_panel_border', '#dee2e6'))}33;
            }}
            .markitect-edit-mode .ui-edit-modal-overlay {{
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, 0.5);
                z-index: 999;
                display: flex;
                align-items: center;
                justify-content: center;
                opacity: 0;
                visibility: hidden;
                transition: opacity 0.3s, visibility 0.3s;
            }}
            .markitect-edit-mode .ui-edit-modal-overlay.active {{
                opacity: 1;
                visibility: visible;
            }}
            .markitect-edit-mode .ui-edit-modal {{
                background: {props['editor_panel_bg']};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                box-shadow: 0 8px 32px {props.get('editor_shadow', 'rgba(0,0,0,0.2)')};
                color: {props.get('editor_text_color', '#212529')};
                border-radius: 8px;
                max-width: 600px;
                max-height: 80vh;
                width: 90%;
                overflow: hidden;
                transform: scale(0.9) translateY(-20px);
                transition: transform 0.3s;
            }}
            .markitect-edit-mode .ui-edit-modal-overlay.active .ui-edit-modal {{
                transform: scale(1) translateY(0);
            }}
            .markitect-edit-mode .ui-edit-modal-header {{
                padding: 20px 24px 16px;
                border-bottom: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                display: flex;
                justify-content: space-between;
                align-items: center;
            }}
            .markitect-edit-mode .ui-edit-modal-title {{
                margin: 0;
                font-size: 18px;
                font-weight: 600;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-edit-mode .ui-edit-modal-close {{
                background: none;
                border: none;
                font-size: 24px;
                cursor: pointer;
                color: {props.get('editor_text_color', '#212529')};
                padding: 4px;
                border-radius: 4px;
                width: 32px;
                height: 32px;
                display: flex;
                align-items: center;
                justify-content: center;
                transition: background-color 0.2s;
            }}
            .markitect-edit-mode .ui-edit-modal-close:hover {{
                background: {props.get('editor_button_hover', '#e9ecef')};
            }}
            .markitect-edit-mode .ui-edit-modal-body {{
                padding: 20px 24px;
                overflow-y: auto;
                max-height: 60vh;
            }}
            .markitect-edit-mode .ui-edit-modal-content {{
                white-space: pre-line;
                line-height: 1.5;
                font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif;
                font-size: 14px;
            }}
            .markitect-edit-mode .ui-edit-modal-section {{
                margin-bottom: 16px;
            }}
            .markitect-edit-mode .ui-edit-modal-section:last-child {{
                margin-bottom: 0;
            }}
            .markitect-edit-mode .ui-edit-modal-section-title {{
                font-weight: 600;
                margin-bottom: 8px;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-edit-mode .ui-edit-modal-footer {{
                padding: 16px 24px 20px;
                border-top: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                text-align: right;
            }}

            /* Confirmation Dialog Styles */
            .markitect-edit-mode .ui-edit-confirmation-modal {{
                max-width: 500px;
            }}
            .markitect-edit-mode .ui-edit-confirmation-content {{
                font-size: 16px;
                line-height: 1.5;
                margin-bottom: 24px;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-edit-mode .ui-edit-confirmation-warning {{
                background: {props.get('editor_warning_bg', '#fff3cd')};
                border: 1px solid {props.get('editor_warning_border', '#ffeaa7')};
                color: {props.get('editor_warning_text', '#856404')};
                padding: 12px 16px;
                border-radius: 6px;
                margin: 16px 0;
                font-size: 14px;
            }}
            .markitect-edit-mode .ui-edit-confirmation-buttons {{
                display: flex;
                gap: 12px;
                justify-content: flex-end;
            }}
            .markitect-edit-mode .ui-edit-button-confirm {{
                background: {props.get('editor_danger_button', '#dc3545')};
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 6px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: background-color 0.2s, transform 0.1s;
            }}
            .markitect-edit-mode .ui-edit-button-confirm:hover {{
                background: {props.get('editor_danger_button_hover', '#c82333')};
                transform: translateY(-1px);
            }}
            .markitect-edit-mode .ui-edit-button-confirm:active {{
                transform: translateY(0);
            }}
            .markitect-edit-mode .ui-edit-button-confirm:focus {{
                outline: 2px solid {props.get('editor_focus_color', '#007bff')};
                outline-offset: 2px;
            }}
            .markitect-edit-mode .ui-edit-button-cancel {{
                background: {props.get('editor_secondary_button', '#6c757d')};
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 6px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: background-color 0.2s, transform 0.1s;
            }}
            .markitect-edit-mode .ui-edit-button-cancel:hover {{
                background: {props.get('editor_secondary_button_hover', '#545b62')};
                transform: translateY(-1px);
            }}
            .markitect-edit-mode .ui-edit-button-cancel:active {{
                transform: translateY(0);
            }}
            .markitect-edit-mode .ui-edit-button-cancel:focus {{
                outline: 2px solid {props.get('editor_focus_color', '#007bff')};
                outline-offset: 2px;
            }}

            /* Document Scroll Indicators */
            .ui-scroll-indicator {{
                position: fixed;
                left: 50%;
                transform: translateX(-50%);
                width: 60px;
                height: 30px;
                background: {props.get('editor_panel_bg', '#f8f9fa')};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                border-radius: 15px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                opacity: 0;
                visibility: hidden;
                transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.2s ease, background-color 0.2s ease;
                z-index: 1000;
                box-shadow: 0 4px 12px {props.get('editor_shadow', 'rgba(0,0,0,0.15)')};
            }}
            .ui-scroll-indicator:hover {{
                transform: translateX(-50%) scale(1.05);
            }}
            .ui-scroll-indicator:not(.disabled):hover {{
                background: {props.get('editor_button_hover', '#e9ecef')};
            }}
            .ui-scroll-indicator.active {{
                opacity: 0.9;
                visibility: visible;
            }}
            .ui-scroll-indicator.disabled {{
                background: {props.get('editor_button_active', '#dee2e6')};
                cursor: not-allowed;
                opacity: 0.6;
            }}
            .ui-scroll-indicator.disabled:hover {{
                transform: translateX(-50%);
                background: {props.get('editor_button_active', '#dee2e6')};
            }}
            .ui-scroll-indicator-up {{
                top: 20px;
            }}
            .ui-scroll-indicator-down {{
                bottom: 20px;
            }}
            .ui-scroll-indicator::before {{
                content: '';
                width: 0;
                height: 0;
                border-style: solid;
                transition: border-color 0.2s ease;
            }}
            .ui-scroll-indicator-up::before {{
                border-left: 8px solid transparent;
                border-right: 8px solid transparent;
                border-bottom: 12px solid {props.get('editor_text_color', '#212529')};
            }}
            .ui-scroll-indicator-down::before {{
                border-left: 8px solid transparent;
                border-right: 8px solid transparent;
                border-top: 12px solid {props.get('editor_text_color', '#212529')};
            }}
            .ui-scroll-indicator.disabled.ui-scroll-indicator-up::before {{
                border-bottom-color: {props.get('editor_secondary_button', '#6c757d')};
            }}
            .ui-scroll-indicator.disabled.ui-scroll-indicator-down::before {{
                border-top-color: {props.get('editor_secondary_button', '#6c757d')};
            }}

            /* Insert Mode Specific Styles */
            .markitect-insert-mode .ui-edit-floater-panel {{
                background: {props['editor_panel_bg']};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                box-shadow: 0 4px 12px {props.get('editor_shadow', 'rgba(0,0,0,0.1)')};
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-floater-header {{
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-floater-header h3 {{
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-inline-panel {{
                background: {props['editor_panel_bg']};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                box-shadow: 0 2px 8px {props.get('editor_shadow', 'rgba(0,0,0,0.1)')};
                color: {props.get('editor_text_color', '#212529')};
                border-radius: 8px;
                padding: 12px;
                margin: 8px 0;
            }}
            .markitect-insert-mode .ui-insert-protected-panel {{
                border-left: 4px solid #ff9800;
            }}
            .markitect-insert-mode .ui-insert-heading-display {{
                font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
                font-size: 14px;
                font-weight: bold;
                padding: 8px 12px;
                background: {props.get('editor_warning_bg', '#fff3cd')};
                border: 1px solid {props.get('editor_warning_border', '#ffeaa7')};
                border-radius: 4px;
                border-left: 4px solid #007bff;
                color: {props.get('editor_warning_text', '#856404')};
                margin-bottom: 8px;
            }}
            .markitect-insert-mode .ui-insert-content-editor {{
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                color: {props.get('editor_text_color', '#212529')};
                background: {props.get('editor_button_bg', '#ffffff')};
            }}
            .markitect-insert-mode .ui-insert-content-editor:focus {{
                border-color: {props.get('editor_focus_color', '#007bff')};
                box-shadow: 0 0 0 2px {props.get('editor_focus_color', '#007bff')}33;
            }}
            .markitect-insert-mode .ui-edit-button {{
                background: {props.get('editor_button_bg', '#ffffff')};
                color: {props.get('editor_text_color', '#212529')};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                padding: 8px 12px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 12px;
                min-width: 70px;
                font-weight: 500;
                transition: all 0.2s;
            }}
            .markitect-insert-mode .ui-edit-button:hover {{
                background: {props.get('editor_button_hover', '#e9ecef')};
            }}
            .markitect-insert-mode .ui-edit-button:active,
            .markitect-insert-mode .ui-edit-button.active {{
                background: {props.get('editor_button_active', '#dee2e6')};
            }}
            .markitect-insert-mode .ui-edit-button-accept {{
                background: #4caf50;
                color: white;
            }}
            .markitect-insert-mode .ui-edit-button-accept:hover {{
                background: #388e3c;
            }}
            .markitect-insert-mode .ui-edit-button-cancel {{
                background: #f44336;
                color: white;
            }}
            .markitect-insert-mode .ui-edit-button-cancel:hover {{
                background: #d32f2f;
            }}
            .markitect-insert-mode .ui-edit-button-reset {{
                background: #ff9800;
                color: white;
            }}
            .markitect-insert-mode .ui-edit-button-reset:hover {{
                background: #f57c00;
            }}
            .markitect-insert-mode .ui-edit-section-frame {{
                border: 2px solid {props.get('editor_focus_color', '#007bff')};
                box-shadow: 0 0 0 3px {props.get('editor_focus_color', '#007bff')}33;
            }}

            /* Modal Overlay and Dialog Styles for Insert Mode */
            .markitect-insert-mode .ui-edit-modal-overlay {{
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0, 0, 0, 0.5);
                z-index: 999;
                display: flex;
                align-items: center;
                justify-content: center;
                opacity: 0;
                visibility: hidden;
                transition: opacity 0.3s, visibility 0.3s;
            }}
            .markitect-insert-mode .ui-edit-modal-overlay.active {{
                opacity: 1;
                visibility: visible;
            }}
            .markitect-insert-mode .ui-edit-modal {{
                background: {props['editor_panel_bg']};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                box-shadow: 0 8px 32px {props.get('editor_shadow', 'rgba(0,0,0,0.2)')};
                color: {props.get('editor_text_color', '#212529')};
                border-radius: 8px;
                max-width: 600px;
                max-height: 80vh;
                width: 90%;
                overflow: hidden;
                transform: scale(0.9) translateY(-20px);
                transition: transform 0.3s;
            }}
            .markitect-insert-mode .ui-edit-modal-overlay.active .ui-edit-modal {{
                transform: scale(1) translateY(0);
            }}
            .markitect-insert-mode .ui-edit-modal-header {{
                padding: 20px 24px 16px;
                border-bottom: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                display: flex;
                justify-content: space-between;
                align-items: center;
            }}
            .markitect-insert-mode .ui-edit-modal-title {{
                margin: 0;
                font-size: 18px;
                font-weight: 600;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-modal-close {{
                background: transparent;
                border: none;
                font-size: 24px;
                cursor: pointer;
                color: {props.get('editor_text_color', '#212529')};
                padding: 0;
                width: 32px;
                height: 32px;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 4px;
                transition: background-color 0.2s;
            }}
            .markitect-insert-mode .ui-edit-modal-close:hover {{
                background: {props.get('editor_button_hover', '#e9ecef')};
            }}
            .markitect-insert-mode .ui-edit-modal-body {{
                padding: 20px 24px;
                max-height: 400px;
                overflow-y: auto;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-modal-section {{
                margin-bottom: 8px;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-modal-footer {{
                padding: 16px 24px 20px;
                border-top: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                text-align: right;
            }}

            /* Confirmation Dialog Styles for Insert Mode */
            .markitect-insert-mode .ui-edit-confirmation-modal {{
                max-width: 500px;
            }}
            .markitect-insert-mode .ui-edit-confirmation-content {{
                font-size: 16px;
                line-height: 1.5;
                margin-bottom: 24px;
                color: {props.get('editor_text_color', '#212529')};
            }}
            .markitect-insert-mode .ui-edit-confirmation-warning {{
                background: {props.get('editor_warning_bg', '#fff3cd')};
                color: {props.get('editor_warning_text', '#856404')};
                border: 1px solid {props.get('editor_warning_border', '#ffeaa7')};
                border-radius: 6px;
                padding: 12px 16px;
                margin: 16px 0;
                font-size: 14px;
                line-height: 1.4;
            }}
            .markitect-insert-mode .ui-edit-confirmation-buttons {{
                display: flex;
                gap: 12px;
                justify-content: flex-end;
                margin-top: 24px;
            }}
            .markitect-insert-mode .ui-edit-button-confirm {{
                background: #dc3545;
                color: white;
                border: 1px solid #dc3545;
                padding: 10px 20px;
                border-radius: 6px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s;
            }}
            .markitect-insert-mode .ui-edit-button-confirm:hover {{
                background: #c82333;
                border-color: #bd2130;
            }}
            .markitect-insert-mode .ui-edit-button-cancel {{
                background: {props.get('editor_button_bg', '#ffffff')};
                color: {props.get('editor_text_color', '#212529')};
                border: 1px solid {props.get('editor_panel_border', '#dee2e6')};
                padding: 10px 20px;
                border-radius: 6px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s;
            }}
            .markitect-insert-mode .ui-edit-button-cancel:hover {{
                background: {props.get('editor_button_hover', '#e9ecef')};
            }}
            """

        # Image size CSS with configurable limits
        image_css = f"""
            img {{
                max-width: {image_max_width};
                max-height: {image_max_height};
                height: auto;
                display: block;
                margin: 1rem auto;
            }}"""

        return f"<style>{base_css}{heading_css}{text_css}{element_css}{link_css}{accent_css}{ui_css}{image_css}</style>"

    def _get_legacy_template_css(self, template: str, image_max_width: str = '12cm', image_max_height: str = '20cm') -> str:
        """Legacy CSS generation - kept for backward compatibility."""
        # Import template styles
        from markitect.plugins.builtin.markdown_commands import TEMPLATE_STYLES

        # Use basic as default if no template specified
        if not template or template not in TEMPLATE_STYLES:
            template = 'basic'

        style_config = TEMPLATE_STYLES[template]

        # Base CSS that's common to all templates
        base_css = f"""
            body {{
                font-family: {style_config['font_family']};
                max-width: {style_config['max_width']};
                margin: 0 auto;
                padding: 2rem;
                line-height: 1.6;
                color: {style_config['body_color']};
            }}
            #markdown-content {{
                min-height: 200px;
            }}"""

        # Convert legacy template config to layered format
        legacy_config = TEMPLATE_STYLES[template]
        layered_props = {
            'font_family': legacy_config['font_family'],
            'max_width': legacy_config['max_width'],
            'body_color': legacy_config['body_color'],
        }
        return self._generate_layered_css(layered_props, image_max_width, image_max_height)

    def _generate_html_template(self, markdown_content: str, title: str, css: str = None, template: str = None,
                              edit_mode: bool = False, insert_mode: bool = False, editor_theme: str = 'github', keyboard_shortcuts: bool = True, original_filename: str = 'document', version_info: dict = None, nodogtag: bool = False,
                              image_max_width: str = '12cm', image_max_height: str = '20cm', base64_references: dict = None) -> str:
        """Generate clean HTML template using external template file."""

        # Check if edit/insert mode components are available
        if edit_mode or insert_mode:
            mode_name = "insert mode" if insert_mode else "edit mode"

            # Check if required components exist
            components_to_check = [
                'js/core/section-manager.js',
                'js/components/debug-panel.js',
                'js/components/document-controls.js',
                'js/components/dom-renderer.js'
            ]

            base_path = Path(__file__).parent / 'static'
            missing_components = []

            for component_path in components_to_check:
                script_path = base_path / component_path
                if not script_path.exists():
                    missing_components.append(component_path)

            if missing_components:
                error_msg = f"""
⚠️ WARNING: {mode_name.title()} requested but some components are missing!

Missing components:
{chr(10).join(f'  - {comp}' for comp in missing_components)}

The system will attempt to load {mode_name} but some functionality may be broken.

RECOMMENDATIONS:
1. Restore missing components from git: git show HEAD:markitect/static/js/...
2. Use static mode instead: Remove --edit or --insert flag
3. Check if all editor components were properly restored

FILE: {original_filename}
MODE REQUESTED: {mode_name}
MISSING: {len(missing_components)} components
"""
                print(error_msg)

                # In strict mode, fail fast for missing components
                if self._should_fail_fast():
                    raise FileNotFoundError(f"{mode_name.title()} components missing: {', '.join(missing_components)}")
            else:
                print(f"✅ {mode_name.title()} components found - proceeding with interactive editing")

        # Add dogtag to markdown content if not disabled
        if not nodogtag:
            import datetime
            import getpass

            now = datetime.datetime.now()
            datetime_str = now.strftime("%Y-%m-%d %H:%M:%S")
            try:
                username = getpass.getuser()
            except:
                username = "user"

            # Create username link only for 'worsch', otherwise just show username
            if username == 'worsch':
                username_link = f'<a href="https://coulomb.social/open/worsch" target="_blank">{username}</a>'
            else:
                username_link = username

            dogtag = f'\n\n---\n*-- html from markdown by <a href="https://coulomb.social/open/MarkiTect" target="_blank">MarkiTect</a> on {datetime_str} by {username_link}*'
            markdown_content_with_dogtag = markdown_content + dogtag
        else:
            markdown_content_with_dogtag = markdown_content
            dogtag = ""

        # Choose template based on mode
        if edit_mode or insert_mode:
            return self._generate_clean_edit_mode_html(
                markdown_content=markdown_content,
                markdown_content_with_dogtag=markdown_content_with_dogtag,
                dogtag=dogtag,
                title=title,
                css=css,
                template=template,
                edit_mode=edit_mode,
                insert_mode=insert_mode,
                editor_theme=editor_theme,
                keyboard_shortcuts=keyboard_shortcuts,
                original_filename=original_filename,
                version_info=version_info,
                image_max_width=image_max_width,
                image_max_height=image_max_height,
                base64_references=base64_references
            )

        # Legacy edit mode (will be removed)
        if False:  # edit_mode or insert_mode:
            # Use the original embedded template for edit/insert modes
            mode_class = 'markitect-edit-mode' if edit_mode else 'markitect-insert-mode'

            # Convert data to JavaScript-safe strings
            js_markdown_content = json.dumps(markdown_content)
            js_markdown_content_with_dogtag = json.dumps(markdown_content_with_dogtag)
            js_dogtag_content = json.dumps(dogtag)
            js_base64_references = json.dumps(base64_references or {})

            # Get editor configuration
            version_str = f"{version_info['repo_name']} v{version_info['version']}{version_info['git_info']}" if version_info else "Markitect v0.5.0.dev"

            if edit_mode:
                editor_config = f"""
        const MARKITECT_EDIT_MODE = true;
        const MARKITECT_EDITOR_CONFIG = {{
            mode: 'edit',
            theme: '{editor_theme}',
            keyboardShortcuts: {str(keyboard_shortcuts).lower()},
            autosave: false,
            sections: true,
            originalFilename: '{original_filename}',
            version: '{version_str}',
            repoName: '{version_info['repo_name'] if version_info else 'Markitect'}'
        }};
        window.editorConfig = MARKITECT_EDITOR_CONFIG;"""
            else:  # insert_mode
                editor_config = f"""
        const MARKITECT_INSERT_MODE = true;
        const MARKITECT_EDITOR_CONFIG = {{
            mode: 'insert',
            restrictedHeadingLevels: [1, 2, 3],
            theme: '{editor_theme}',
            keyboardShortcuts: {str(keyboard_shortcuts).lower()},
            autosave: false,
            sections: true,
            originalFilename: '{original_filename}',
            version: '{version_str}',
            repoName: '{version_info['repo_name'] if version_info else 'Markitect'}'
        }};
        window.editorConfig = MARKITECT_EDITOR_CONFIG;"""

            # Get editor scripts
            editor_scripts = self._get_clean_editor_scripts()

            # Generate CSS
            css_content = self._get_template_css(template, image_max_width, image_max_height) if not css else css

            # Use the original embedded template structure
            template_content = """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{title}}</title>
    {css_content}

    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"
            onload="window.markitectMarkedLoaded = true"
            onerror="window.markitectMarkedError = true"></script>
</head>
<body class="{mode_class}">

    <div id="markdown-content"></div>

    <script>
        const markdownContent = {js_markdown_content};
        const markdownContentWithDogtag = {js_markdown_content_with_dogtag};
        const dogtagContent = {js_dogtag_content};
        window.markitectBase64References = {js_base64_references};
        {editor_config}

        {editor_scripts}

        // Always render content first (graceful degradation)
        document.addEventListener('DOMContentLoaded', function() {
            console.log("🎯 Rendering content in {mode_type} mode...");

            // Initialize edit/insert capabilities first (always needed)
            if ((typeof MARKITECT_EDIT_MODE !== 'undefined' && MARKITECT_EDIT_MODE) ||
                (typeof MARKITECT_INSERT_MODE !== 'undefined' && MARKITECT_INSERT_MODE)) {
                const mode = (typeof MARKITECT_INSERT_MODE !== 'undefined' && MARKITECT_INSERT_MODE) ? 'insert' : 'edit';
                console.log('🚀 Initializing clean ' + mode + ' capabilities...');
                try {
                    console.log("Creating clean editor instance...");
                    initializeCleanEditor();
                    if (mode === 'insert') {
                        console.log("✅ Clean insert mode active - click any section to edit (headings 1-3 protected)");
                    } else {
                        console.log("✅ Clean edit mode active - click any section to edit");
                    }
                } catch (error) {
                    console.error('❌ Clean ' + mode + ' mode failed to initialize:', error);
                }
            }

            // Check if modular components are being used for content rendering
            if (typeof SectionManager !== 'undefined') {
                console.log("✓ Modular components detected - skipping fallback content rendering");
                console.log("✓ Content will be rendered by modular architecture");
                return;
            }

            const contentDiv = document.getElementById('markdown-content');

            // Step 1: Ensure content is always displayed (fallback for non-modular mode)
            if (contentDiv) {
                if (typeof marked !== 'undefined') {
                    try {
                        const html = marked.parse(markdownContentWithDogtag);
                        // Add target="_blank" to all links
                        const htmlWithTargetBlank = html.replace(/<a href="([^"]*)"([^>]*)>/g, '<a href="$1" target="_blank"$2>');
                        contentDiv.innerHTML = htmlWithTargetBlank;
                        console.log("✓ Content rendered successfully");
                    } catch (error) {
                        contentDiv.innerHTML = '<p>Error rendering markdown: ' + error.message + '</p>';
                        console.error("Content rendered with errors");
                        console.error("Markdown parsing failed:", error.message);
                    }
                } else {
                    // Fallback: display raw markdown with basic formatting
                    const fallbackHtml = markdownContent
                        .replace(/^# (.*$)/gim, '<h1>$1</h1>')
                        .replace(/^## (.*$)/gim, '<h2>$1</h2>')
                        .replace(/^### (.*$)/gim, '<h3>$1</h3>')
                        .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')
                        .replace(/\\*(.*?)\\*/g, '<em>$1</em>')
                        .replace(/^- (.*$)/gim, '<li>$1</li>')
                        .replace(/\\n\\n/g, '<br><br>')
                        .replace(/\\n/g, '<br>');
                    contentDiv.innerHTML = '<div style="white-space: pre-wrap;">' + fallbackHtml + '</div>';
                    console.warn("Content rendered with fallback parser");
                    console.warn("CDN library failed to load - using basic fallback rendering");
                }
            }

            // Step 3: Initialize scroll indicators
            try {
                initializeScrollIndicators();
            } catch (error) {
                console.error("Scroll indicators failed to initialize:", error);
            }
        });

        window.addEventListener('load', function() {
            if (window.markitectMarkedError) {
                console.error("CDN library failed to load - network or firewall blocking marked.js");
            }
        });
    </script>
</body>
</html>"""

            # Determine version string for template substitution
            if version_info:
                version_str = f"{version_info['repo_name']} v{version_info['version']}{version_info['git_info']}"
            else:
                version_str = "0.5.0.dev"

            # Replace template placeholders (same as static mode)
            html_template = template_content.replace('{title}', title)
            html_template = html_template.replace('{version}', version_str)

            # Replace JavaScript variables with properly escaped JSON
            html_template = html_template.replace('{js_markdown_content}', js_markdown_content)
            html_template = html_template.replace('{js_markdown_content_with_dogtag}', js_markdown_content_with_dogtag)
            html_template = html_template.replace('{js_dogtag_content}', js_dogtag_content)
            html_template = html_template.replace('{js_base64_references}', js_base64_references)
            html_template = html_template.replace('{editor_config}', editor_config)
            html_template = html_template.replace('{editor_scripts}', editor_scripts)
            html_template = html_template.replace('{css_content}', css_content)
            html_template = html_template.replace('{mode_class}', mode_class)
            html_template = html_template.replace('{mode_type}', 'insert' if insert_mode else 'edit')

            # No {content} placeholder in edit mode - content is handled by JavaScript
            return html_template

        else:
            # Use external template for static viewing mode
            template_path = Path(__file__).parent / 'templates' / 'document.html'
            if not template_path.exists():
                # Fallback to a minimal template if external template not found
                template_content = """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{title}</title>
    <meta name="generator" content="Markitect {version}">
</head>
<body>
    <div id="markitect-content">{content}</div>
</body>
</html>"""
            else:
                template_content = template_path.read_text(encoding='utf-8')

        # Determine version string
        if version_info:
            version_str = f"{version_info['repo_name']} v{version_info['version']}{version_info['git_info']}"
        else:
            version_str = "0.5.0.dev"

        # Convert markdown to HTML (basic conversion)
        try:
            import markdown
            html_content = markdown.markdown(markdown_content_with_dogtag, extensions=['extra', 'codehilite', 'toc'])
        except ImportError:
            # Fallback: simple line breaks and basic formatting
            html_content = markdown_content_with_dogtag.replace('\n\n', '</p><p>').replace('\n', '<br>')
            html_content = f'<p>{html_content}</p>'

        # Generate or read CSS content
        if css:
            # If css is a file path, read it
            css_path = Path(css)
            if css_path.exists() and css_path.is_file():
                css_content = f'<style>\n{css_path.read_text(encoding="utf-8")}\n</style>'
            else:
                # Assume it's raw CSS content
                css_content = f'<style>\n{css}\n</style>'
        else:
            # Use template-based CSS generation
            css_content = self._get_template_css(template, image_max_width, image_max_height)

        # Replace template placeholders using safe string replacement
        # This avoids conflicts with CSS curly braces
        html_template = template_content.replace('{title}', title)
        html_template = html_template.replace('{version}', version_str)
        html_template = html_template.replace('{content}', html_content)
        html_template = html_template.replace('{css_content}', css_content)

        return html_template

    def _generate_clean_edit_mode_html(self, markdown_content: str, markdown_content_with_dogtag: str, dogtag: str, title: str, css: str = None, template: str = None, edit_mode: bool = False, insert_mode: bool = False, editor_theme: str = 'github', keyboard_shortcuts: bool = True, original_filename: str = 'document', version_info: dict = None, image_max_width: str = '12cm', image_max_height: str = '20cm', base64_references: dict = None) -> str:
        """Generate clean HTML for edit mode using external script references like non-edit mode."""

        # Use the fixed template that follows non-edit pattern
        template_path = Path(__file__).parent / 'templates' / 'edit-mode-fixed.html'
        if not template_path.exists():
            raise FileNotFoundError(f"Fixed edit mode template not found: {template_path}")

        template_content = template_path.read_text(encoding='utf-8')

        # Generate or read CSS content
        if css:
            # If css is a file path, read it
            css_path = Path(css)
            if css_path.exists() and css_path.is_file():
                css_content = f'<style>\n{css_path.read_text(encoding="utf-8")}\n</style>'
            else:
                # Assume it's raw CSS content
                css_content = f'<style>\n{css}\n</style>'
        else:
            # Use template-based CSS generation
            css_content = self._get_template_css(template, image_max_width, image_max_height)

        # Create configuration object - ONLY dynamic data interface
        config = {
            'markdownContent': markdown_content,
            'markdownContentWithDogtag': markdown_content_with_dogtag,
            'dogtagContent': dogtag,
            'mode': 'insert' if insert_mode else 'edit',
            'theme': editor_theme,
            'keyboardShortcuts': keyboard_shortcuts,
            'autosave': False,
            'sections': True,
            'originalFilename': original_filename,
            'base64References': base64_references or {}
        }

        # Add version info
        if version_info:
            config['version'] = f"{version_info['repo_name']} v{version_info['version']}{version_info['git_info']}"
            config['repoName'] = version_info['repo_name']
        else:
            # Get version from CLI command as fallback
            import subprocess
            try:
                result = subprocess.run(['markitect', '--version'], capture_output=True, text=True, timeout=5)
                actual_version = result.stdout.strip() if result.returncode == 0 else '0.8.1.dev44+gf788ccdfd.d20251114'
            except:
                actual_version = '0.8.1.dev44+gf788ccdfd.d20251114'
            config['version'] = f'Markitect v{actual_version}'
            config['repoName'] = 'Markitect'

        # Add insert mode specific config
        if insert_mode:
            config['restrictedHeadingLevels'] = [1, 2, 3]

        # Convert config to JSON - This is the ONLY place Python data enters JavaScript
        config_json = json.dumps(config, ensure_ascii=False, separators=(',', ':'))

        # Mode class for body
        mode_class = 'markitect-insert-mode' if insert_mode else 'markitect-edit-mode'

        # Version string for template
        version_str = config['version']

        # Generate fallback content (like non-edit mode)
        fallback_content = self._render_markdown_to_html(markdown_content_with_dogtag)

        # Replace template placeholders - all safe static replacements
        html_template = template_content.replace('{title}', title)
        html_template = html_template.replace('{version}', version_str)
        html_template = html_template.replace('{css_content}', css_content)
        html_template = html_template.replace('{mode_class}', mode_class)
        html_template = html_template.replace('{config_json}', config_json)
        html_template = html_template.replace('{fallback_content}', fallback_content)

        return html_template

    def _render_markdown_to_html(self, markdown_content: str) -> str:
        """Render markdown to HTML for fallback content (same as non-edit mode)."""
        try:
            from markdown import markdown
            # Use basic markdown rendering
            html_content = markdown(markdown_content)

            # Add target="_blank" to all links (same as non-edit mode)
            import re
            html_content = re.sub(
                r'<a href="([^"]*)"([^>]*)>',
                r'<a href="\1" target="_blank"\2>',
                html_content
            )

            return html_content

        except ImportError:
            # Fallback if markdown not available
            import html
            lines = markdown_content.split('\n')
            html_lines = []

            for line in lines:
                line = line.strip()
                if line.startswith('# '):
                    html_lines.append(f'<h1>{html.escape(line[2:])}</h1>')
                elif line.startswith('## '):
                    html_lines.append(f'<h2>{html.escape(line[3:])}</h2>')
                elif line.startswith('### '):
                    html_lines.append(f'<h3>{html.escape(line[4:])}</h3>')
                elif line:
                    html_lines.append(f'<p>{html.escape(line)}</p>')

            return '\n'.join(html_lines)


    def _should_fail_fast(self) -> bool:
        """
        Determine if we should fail fast (development mode) or continue gracefully (production mode).

        Fail fast in:
        - Development environments (localhost, 127.0.0.1)
        - When strict mode is enabled via environment variable
        - When running in test environments

        Continue gracefully in:
        - Production environments
        - When explicitly disabled via environment variable
        """
        import os

        # Check environment variables first
        strict_env = os.getenv('MARKITECT_STRICT_MODE', '').lower()
        if strict_env in ('true', '1', 'yes', 'on'):
            return True
        if strict_env in ('false', '0', 'no', 'off'):
            return False

        # Check if we're in a development environment
        # This mimics the JavaScript strict mode detection
        try:
            import socket
            hostname = socket.gethostname().lower()
            if 'localhost' in hostname or hostname.startswith('127.') or 'dev' in hostname:
                return True
        except:
            pass

        # Check for test environment indicators
        if any(env in os.environ for env in ['PYTEST_CURRENT_TEST', 'CI', 'CONTINUOUS_INTEGRATION', 'TESTING']):
            return True

        # Default to graceful handling in production
        return False

    def _get_clean_editor_scripts_backup(self) -> str:
        """Legacy method kept for reference - should not be used."""
        # This method contained embedded JavaScript that has been moved to external files
        return ""

    def _get_clean_editor_scripts(self) -> str:
        """Load the modular editor JavaScript components from external files."""
        from pathlib import Path

        # Define the modular components to load in order
        components = [
            'js/core/debug-system.js',
            'js/core/section-manager.js',
            'js/components/debug-panel.js',
            'js/components/document-controls.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/main.js'
        ]

        base_path = Path(__file__).parent / 'static'
        combined_script = []

        # Load each component
        for component_path in components:
            script_path = base_path / component_path
            if script_path.exists():
                try:
                    content = script_path.read_text(encoding='utf-8')
                    combined_script.append(f"// === {component_path} ===")
                    combined_script.append(content)
                    combined_script.append("")  # Add blank line between components
                except Exception as e:
                    print(f"Warning: Could not read {component_path}: {e}")
                    combined_script.append(f"console.error('Failed to load {component_path}');")
            else:
                print(f"Warning: {component_path} not found at {script_path}")
                combined_script.append(f"console.error('{component_path} file not found');")

        # Add initialization script to wire up the components
        initialization_script = """
// === Missing Function Definitions ===
function initializeCleanEditor() {
    console.log('✅ initializeCleanEditor: Modular components will handle initialization');
    // This function was missing - the modular components handle initialization automatically
    // No additional action needed here
}

function initializeScrollIndicators() {
    console.log('✅ initializeScrollIndicators: Basic scroll indicators initialized');
    // Simple scroll indicator implementation for document navigation
    // This is a placeholder - can be enhanced later
}

// === Component Initialization ===
document.addEventListener('DOMContentLoaded', function() {
    // Create container for the markdown content
    const container = document.getElementById('markdown-content') || document.body;

    // Initialize components
    const sectionManager = new SectionManager();
    const domRenderer = new DOMRenderer(sectionManager, container);
    const debugPanel = new DebugPanel();
    const documentControls = new DocumentControls();

    // Create document controls
    documentControls.create();

    // Step 4: Initialize modern Control-based architecture with compass positioning
    console.log("🎛️ Initializing modern Control system with compass positioning...");

    // ContentsControl (positioned upper left - nw)
    const contentsControl = new ContentsControl();
    contentsControl.control.config.position = 'nw';  // Upper left
    contentsControl.createControl();
    window.contentsControl = contentsControl;

    // StatusControl (positioned right - e)
    const statusControl = new StatusControl();
    statusControl.control.config.position = 'e';  // Right
    statusControl.createControl();
    window.statusControl = statusControl;

    // DebugControl (positioned lower right - se)
    const debugControl = new DebugControl();
    debugControl.control.config.position = 'se';  // Lower right
    debugControl.createControl();
    window.debugControl = debugControl;

    // EditControl (positioned upper right - ne)
    const editControl = new EditControl();
    editControl.control.config.position = 'ne';  // Upper right
    editControl.createControl();
    window.editControl = editControl;

    console.log("🎛️ Modern Control system initialized with compass positioning");

    // Wire up event handlers
    documentControls.setEventHandlers({
        'save-document': () => {
            console.log('Save document clicked');
            try {
                // Get current markdown content from section manager
                const currentMarkdown = sectionManager.getDocumentMarkdown();

                // Create filename with timestamp suffix following the established convention
                const now = new Date();
                const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-').replace('T', '-');

                // Extract original filename from config or use default
                const originalFilename = window.editorConfig?.originalFilename || 'document';
                const editedFilename = `${originalFilename}-edited-${timestamp}.md`;

                // Create and download the file
                const blob = new Blob([currentMarkdown], { type: 'text/markdown' });
                const url = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = editedFilename;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(url);

                // Log success to debug panel
                debugPanel.addMessage(`Document saved as: ${editedFilename}`, 'SUCCESS');
                console.log(`Document successfully saved as: ${editedFilename}`);

            } catch (error) {
                debugPanel.addMessage(`Save failed: ${error.message}`, 'ERROR');
                console.error('Save error:', error);
            }
        },
        'reset-all': () => {
            console.log('Reset all clicked');
            // Hide any open editors
            domRenderer.hideCurrentEditor();
            // Reset all sections to original state
            const allSections = Array.from(sectionManager.sections.values());
            allSections.forEach(section => {
                section.resetToOriginal();
            });
            // Re-render all sections
            domRenderer.renderAllSections(allSections);
            debugPanel.addMessage(`Reset all sections to original state`, 'INFO');
        },
        'show-status': () => {
            const status = sectionManager.getDocumentStatus();
            alert(`Document Status:\\nTotal Sections: ${status.totalSections}\\nEditing Sections: ${status.editingSections}`);
        },
        'toggle-debug': () => {
            debugPanel.toggle();
        }
    });

    // Set up debug panel integration
    sectionManager.on('sections-created', (data) => {
        debugPanel.addMessage(`Created ${data.count} sections`, 'INFO');
    });

    sectionManager.on('edit-started', (data) => {
        debugPanel.addMessage(`Edit started for section: ${data.sectionId}`, 'DEBUG');
    });

    sectionManager.on('changes-accepted', (data) => {
        debugPanel.addMessage(`Changes accepted for section: ${data.sectionId}`, 'SUCCESS');
        // Re-render the section to show updated content
        const section = sectionManager.sections.get(data.sectionId);
        if (section) {
            const sectionElement = domRenderer.findSectionElement(data.sectionId);
            if (sectionElement) {
                const newElement = domRenderer.renderSection(section);
                sectionElement.parentNode.replaceChild(newElement, sectionElement);
                debugPanel.addMessage(`DOM updated for section: ${data.sectionId}`, 'INFO');
            }
        }
    });

    sectionManager.on('changes-cancelled', (data) => {
        debugPanel.addMessage(`Changes cancelled for section: ${data.sectionId}`, 'WARNING');
    });

    // Initialize with markdown content
    const markdownToRender = markdownContent || '';
    if (markdownToRender.trim()) {
        const sections = sectionManager.createSectionsFromMarkdown(markdownToRender);
        domRenderer.renderAllSections(sections);
        debugPanel.addMessage(`Initialized with ${sections.length} sections`, 'INFO');
    } else {
        debugPanel.addMessage('No markdown content to initialize', 'WARNING');
    }

    // Make components globally available for debugging
    window.markitectComponents = {
        sectionManager,
        domRenderer,
        debugPanel,
        documentControls
    };

    console.log('Markitect modular editor initialized successfully');
});
"""

        combined_script.append(initialization_script)
        return '\n'.join(combined_script)
