"""HTML exporter for Data Docs.

This module provides the HTML exporter which is the default output format.
"""

from __future__ import annotations

import re
from typing import TYPE_CHECKING

from truthound.datadocs.exporters.base import BaseExporter, ExportOptions

if TYPE_CHECKING:
    from truthound.datadocs.engine.context import ReportContext


class HtmlExporter(BaseExporter):
    """HTML output exporter.

    This is the default exporter that outputs clean HTML.

    Options:
        minify: Minify the HTML output.
        inline_styles: Inline CSS styles.
        include_metadata: Include metadata comments.
    """

    def __init__(
        self,
        minify: bool = False,
        inline_styles: bool = False,
        include_metadata: bool = True,
        options: ExportOptions | None = None,
        name: str | None = None,
    ) -> None:
        """Initialize the HTML exporter.

        Args:
            minify: Minify the output.
            inline_styles: Inline CSS styles.
            include_metadata: Include metadata comments.
            options: Export options.
            name: Exporter name.
        """
        super().__init__(options=options, name=name or "HtmlExporter")
        self._minify = minify
        self._inline_styles = inline_styles
        self._include_metadata = include_metadata

    @property
    def format(self) -> str:
        return "html"

    def _do_export(
        self,
        content: str,
        ctx: "ReportContext",
    ) -> str:
        """Export to HTML.

        Args:
            content: Rendered HTML content.
            ctx: Report context.

        Returns:
            HTML string.
        """
        html = content

        # Add metadata comment if requested
        if self._include_metadata:
            metadata = ctx.data.metadata
            meta_comment = f"""<!--
    Generated by Truthound
    Title: {metadata.get('title', '')}
    Generated: {metadata.get('generated_at', '')}
    Locale: {ctx.locale}
    Theme: {ctx.theme}
-->
"""
            # Insert after DOCTYPE
            if html.lower().startswith("<!doctype"):
                insert_pos = html.find(">") + 1
                html = html[:insert_pos] + "\n" + meta_comment + html[insert_pos:]
            else:
                html = meta_comment + html

        # Minify if requested
        if self._minify:
            html = self._minify_html(html)

        return html

    def _minify_html(self, html: str) -> str:
        """Minify HTML content.

        Args:
            html: HTML string.

        Returns:
            Minified HTML.
        """
        # Remove comments (except conditional comments)
        html = re.sub(r"<!--(?!\[if).*?-->", "", html, flags=re.DOTALL)

        # Remove whitespace between tags
        html = re.sub(r">\s+<", "><", html)

        # Remove leading/trailing whitespace in lines
        lines = [line.strip() for line in html.split("\n")]
        html = "".join(lines)

        # Remove multiple spaces
        html = re.sub(r"\s{2,}", " ", html)

        return html


class SelfContainedHtmlExporter(HtmlExporter):
    """Exporter that produces self-contained HTML.

    All external resources (CSS, JS, images) are inlined
    for offline viewing.
    """

    def __init__(
        self,
        embed_images: bool = True,
        embed_fonts: bool = False,
        options: ExportOptions | None = None,
        name: str | None = None,
    ) -> None:
        """Initialize the self-contained HTML exporter.

        Args:
            embed_images: Embed images as base64.
            embed_fonts: Embed fonts as base64.
            options: Export options.
            name: Exporter name.
        """
        super().__init__(
            minify=False,
            inline_styles=True,
            include_metadata=True,
            options=options,
            name=name or "SelfContainedHtmlExporter",
        )
        self._embed_images = embed_images
        self._embed_fonts = embed_fonts

    def _do_export(
        self,
        content: str,
        ctx: "ReportContext",
    ) -> str:
        """Export to self-contained HTML.

        Args:
            content: Rendered HTML content.
            ctx: Report context.

        Returns:
            Self-contained HTML string.
        """
        html = super()._do_export(content, ctx)

        # Remove external CSS links (CSS should already be inlined)
        html = re.sub(
            r'<link[^>]+rel=["\']stylesheet["\'][^>]*>',
            "",
            html,
            flags=re.IGNORECASE,
        )

        # Remove external JS references (except CDN charts)
        # Keep chart libraries as they're needed for rendering

        return html
