"""Markdown exporter for Data Docs.

This module provides Markdown export functionality.
"""

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 MarkdownExporter(BaseExporter):
    """Markdown output exporter.

    Converts HTML reports to Markdown format.

    Options:
        include_toc: Include table of contents.
        github_flavored: Use GitHub-flavored markdown.
        include_metadata: Include YAML frontmatter.
    """

    def __init__(
        self,
        include_toc: bool = True,
        github_flavored: bool = True,
        include_metadata: bool = True,
        options: ExportOptions | None = None,
        name: str | None = None,
    ) -> None:
        """Initialize the Markdown exporter.

        Args:
            include_toc: Include table of contents.
            github_flavored: Use GitHub-flavored markdown.
            include_metadata: Include YAML frontmatter.
            options: Export options.
            name: Exporter name.
        """
        super().__init__(options=options, name=name or "MarkdownExporter")
        self._include_toc = include_toc
        self._github_flavored = github_flavored
        self._include_metadata = include_metadata

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

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

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

        Returns:
            Markdown string.
        """
        data = ctx.data
        metadata = data.metadata

        parts = []

        # YAML frontmatter
        if self._include_metadata:
            parts.append(self._generate_frontmatter(metadata, ctx))

        # Title
        title = metadata.get("title", "Data Quality Report")
        parts.append(f"# {title}\n")

        if metadata.get("subtitle"):
            parts.append(f"*{metadata['subtitle']}*\n")

        # Table of contents
        if self._include_toc and data.sections:
            parts.append(self._generate_toc(data.sections))

        # Quality score
        if metadata.get("quality_score"):
            parts.append(self._format_quality_score(metadata["quality_score"]))

        # Sections
        for section_name, section_data in data.sections.items():
            parts.append(self._format_section(section_name, section_data))

        # Alerts
        if data.alerts:
            parts.append(self._format_alerts(data.alerts))

        # Recommendations
        if data.recommendations:
            parts.append(self._format_recommendations(data.recommendations))

        # Footer
        parts.append("\n---\n")
        parts.append("*Generated by Truthound*\n")

        return "\n".join(parts)

    def _generate_frontmatter(self, metadata: dict, ctx: "ReportContext") -> str:
        """Generate YAML frontmatter.

        Args:
            metadata: Report metadata.
            ctx: Report context.

        Returns:
            YAML frontmatter string.
        """
        lines = ["---"]
        lines.append(f"title: \"{metadata.get('title', 'Data Quality Report')}\"")
        if metadata.get("subtitle"):
            lines.append(f"subtitle: \"{metadata['subtitle']}\"")
        lines.append(f"generated_at: \"{metadata.get('generated_at', '')}\"")
        lines.append(f"locale: {ctx.locale}")
        lines.append(f"theme: {ctx.theme}")
        lines.append("---\n")
        return "\n".join(lines)

    def _generate_toc(self, sections: dict) -> str:
        """Generate table of contents.

        Args:
            sections: Report sections.

        Returns:
            TOC markdown string.
        """
        lines = ["## Table of Contents\n"]
        for section_name in sections.keys():
            display_name = section_name.replace("_", " ").title()
            anchor = section_name.lower().replace(" ", "-")
            lines.append(f"- [{display_name}](#{anchor})")
        lines.append("")
        return "\n".join(lines)

    def _format_section(self, name: str, data: dict | list | str) -> str:
        """Format a section.

        Args:
            name: Section name.
            data: Section data.

        Returns:
            Markdown string.
        """
        display_name = name.replace("_", " ").title()
        lines = [f"## {display_name}\n"]

        if isinstance(data, dict):
            # Format as definition list or table
            if self._github_flavored and len(data) > 3:
                # Use table for larger datasets
                lines.append("| Property | Value |")
                lines.append("|----------|-------|")
                for key, value in data.items():
                    key_display = key.replace("_", " ").title()
                    lines.append(f"| {key_display} | {self._format_value(value)} |")
            else:
                # Use simple list
                for key, value in data.items():
                    key_display = key.replace("_", " ").title()
                    lines.append(f"- **{key_display}**: {self._format_value(value)}")
        elif isinstance(data, list):
            for item in data:
                if isinstance(item, dict):
                    # Format dict item
                    first_value = list(item.values())[0] if item else ""
                    lines.append(f"- {first_value}")
                else:
                    lines.append(f"- {item}")
        else:
            lines.append(str(data))

        lines.append("")
        return "\n".join(lines)

    def _format_value(self, value) -> str:
        """Format a value for markdown.

        Args:
            value: Value to format.

        Returns:
            Formatted string.
        """
        if isinstance(value, float):
            if value < 1:
                return f"{value:.1%}"
            return f"{value:,.2f}"
        elif isinstance(value, int):
            return f"{value:,}"
        elif isinstance(value, list):
            return ", ".join(str(v) for v in value[:5])
        elif isinstance(value, dict):
            return str(value)
        return str(value)

    def _format_quality_score(self, quality_score: dict) -> str:
        """Format quality score section.

        Args:
            quality_score: Quality score data.

        Returns:
            Markdown string.
        """
        lines = ["## Quality Score\n"]

        overall = quality_score.get("overall", 0)
        grade = quality_score.get("grade", "N/A")

        lines.append(f"**Overall Score: {overall}** (Grade: {grade})\n")

        dimensions = quality_score.get("dimensions", {})
        if dimensions:
            lines.append("### Dimensions\n")
            lines.append("| Dimension | Score |")
            lines.append("|-----------|-------|")
            for dim, score in dimensions.items():
                bar = "█" * int(score / 10) + "░" * (10 - int(score / 10))
                lines.append(f"| {dim.title()} | {bar} {score}% |")

        lines.append("")
        return "\n".join(lines)

    def _format_alerts(self, alerts: list) -> str:
        """Format alerts section.

        Args:
            alerts: List of alerts.

        Returns:
            Markdown string.
        """
        lines = ["## Alerts\n"]

        severity_emoji = {
            "info": "ℹ️",
            "warning": "⚠️",
            "error": "❌",
            "critical": "🚨",
        }

        for alert in alerts:
            severity = alert.get("severity", "info").lower()
            emoji = severity_emoji.get(severity, "•")
            title = alert.get("title", "Alert")
            message = alert.get("message", "")

            lines.append(f"### {emoji} {title}")
            lines.append(f"{message}\n")

            if alert.get("suggestion"):
                lines.append(f"*Suggestion: {alert['suggestion']}*\n")

        return "\n".join(lines)

    def _format_recommendations(self, recommendations: list) -> str:
        """Format recommendations section.

        Args:
            recommendations: List of recommendations.

        Returns:
            Markdown string.
        """
        lines = ["## Recommendations\n"]

        for i, rec in enumerate(recommendations, 1):
            lines.append(f"{i}. {rec}")

        lines.append("")
        return "\n".join(lines)
