"""LaTeX exporter for chronobox reports.

Generates LaTeX documents with booktabs tables, figure references,
and professional typesetting.
"""

from __future__ import annotations

from typing import Any


class LaTeXExporter:
    """Export report context to LaTeX document.

    Features:
    - Professional tables with booktabs
    - Figure references (PNG/PDF)
    - Proper sections and subsections
    - Metadata footer
    - Compiles with pdflatex
    """

    def export(self, context: dict[str, Any]) -> str:
        """Export context to LaTeX string.

        Parameters
        ----------
        context : dict
            Template context from a transformer.

        Returns
        -------
        str
            Complete LaTeX document.
        """
        title = context.get("title", "Report")
        sections = context.get("sections", [])
        model_info = context.get("model_info", {})

        preamble = self._build_preamble(title)
        body = self._build_body(title, model_info, sections)

        return f"""{preamble}

\\begin{{document}}

{body}

\\end{{document}}
"""

    def _build_preamble(self, title: str) -> str:
        """Build LaTeX preamble.

        Parameters
        ----------
        title : str
            Document title.

        Returns
        -------
        str
            LaTeX preamble.
        """
        return (
            r"""\documentclass[11pt,a4paper]{article}

% Encoding and fonts
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}

% Layout
\usepackage[margin=2.5cm]{geometry}
\usepackage{parskip}

% Tables
\usepackage{booktabs}
\usepackage{tabularx}
\usepackage{multirow}

% Graphics
\usepackage{graphicx}
\usepackage{float}

% Colors
\usepackage[table]{xcolor}

% Links
\usepackage{hyperref}
\hypersetup{colorlinks=true, linkcolor=blue, urlcolor=blue}

% Header/Footer
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
\rhead{chronobox}
\lhead{"""
            + title
            + r"""}
\rfoot{\thepage}

% Math
\usepackage{amsmath,amssymb}

% Title
\title{"""
            + title
            + r"""}
\author{Generated by \texttt{chronobox}}
\date{\today}"""
        )

    def _build_body(
        self,
        title: str,
        model_info: dict[str, Any],
        sections: list[dict[str, Any]],
    ) -> str:
        """Build LaTeX body.

        Parameters
        ----------
        title : str
            Document title.
        model_info : dict
            Model information.
        sections : list[dict]
            Report sections.

        Returns
        -------
        str
            LaTeX body.
        """
        parts = [r"\maketitle", ""]

        # Model info
        if model_info:
            parts.append(r"\section{Model Information}")
            parts.append(r"\begin{itemize}")
            for key, value in model_info.items():
                label = key.replace("_", " ").title()
                parts.append(f"  \\item \\textbf{{{label}}}: {value}")
            parts.append(r"\end{itemize}")
            parts.append("")

        # Sections
        for section in sections:
            sec_title = section.get("title", "Section")
            content = section.get("content", "")
            table = section.get("table")

            # Escape special LaTeX characters in title
            sec_title_safe = self._escape_latex(sec_title)
            parts.append(f"\\section{{{sec_title_safe}}}")
            parts.append("")

            if content:
                parts.append(self._escape_latex(str(content)))
                parts.append("")

            if table:
                parts.append(self._table_to_latex(table))
                parts.append("")

        # Footer
        parts.append("")
        parts.append(r"\vfill")
        parts.append(r"\noindent\rule{\textwidth}{0.4pt}")
        parts.append(r"\small{Generated by \texttt{chronobox} -- \today}")

        return "\n".join(parts)

    def _table_to_latex(self, table: list[dict[str, Any]]) -> str:
        """Convert table data to LaTeX booktabs table.

        Parameters
        ----------
        table : list[dict]
            Table rows.

        Returns
        -------
        str
            LaTeX table.
        """
        if not table:
            return ""

        headers = list(table[0].keys())
        n_cols = len(headers)
        col_spec = "l" + "r" * (n_cols - 1)

        # Header row
        header_str = " & ".join(
            r"\textbf{" + self._escape_latex(h) + "}" for h in headers
        )

        # Data rows
        data_rows = []
        for row in table:
            cells = []
            for h in headers:
                val = row.get(h, "")
                if isinstance(val, float):
                    cells.append(f"{val:.4f}")
                else:
                    cells.append(self._escape_latex(str(val)))
            data_rows.append(" & ".join(cells))

        rows_str = " \\\\\n    ".join(data_rows)

        return f"""\\begin{{table}}[H]
\\centering
\\begin{{tabular}}{{{col_spec}}}
    \\toprule
    {header_str} \\\\
    \\midrule
    {rows_str} \\\\
    \\bottomrule
\\end{{tabular}}
\\end{{table}}"""

    @staticmethod
    def _escape_latex(text: str) -> str:
        """Escape special LaTeX characters.

        Parameters
        ----------
        text : str
            Input text.

        Returns
        -------
        str
            Escaped text.
        """
        special = {
            "&": r"\&",
            "%": r"\%",
            "$": r"\$",
            "#": r"\#",
            "_": r"\_",
            "{": r"\{",
            "}": r"\}",
            "~": r"\textasciitilde{}",
            "^": r"\textasciicircum{}",
        }
        # Don't escape if it looks like a LaTeX command
        if text.startswith("\\"):
            return text
        for char, replacement in special.items():
            text = text.replace(char, replacement)
        return text
