"""
HTML Report Generator for Preliminary Analysis

This module contains all the HTML generation logic for creating comprehensive reports with collapsible sections and interactive elements.
"""

from datetime import datetime
from pathlib import Path

import polars as pl

from imperfekt.analysis.utils.html_reporting_helpers import (
    dataframe_to_html_table,
    fig_to_html,
    get_apple_style_css,
    get_javascript,
)


class PreliminaryHTMLReportGenerator:
    """Generates HTML reports for preliminary analysis results."""

    def __init__(self, analysis_instance):
        """
        Initialize the report generator.

        Args:
            analysis_instance: The Preliminary instance containing results
        """
        self.analysis = analysis_instance

    def generate_report(
        self, report_path: str = "preliminary_report.html", title: str = None
    ) -> Path:
        """
        Generates an HTML report from the analysis results.

        Args:
            report_path: The filename for the HTML report

        Returns:
            Path to the generated report file
        """
        # Get full report path
        full_report_path = self.analysis.save_path / report_path

        # Generate HTML content
        html_content = self._generate_html_content(title=title)

        # Write to file
        with open(full_report_path, "w", encoding="utf-8") as f:
            f.write(html_content)

        return full_report_path

    def _generate_html_content(self, title: str = None) -> str:
        """Generates the complete HTML content for the report."""
        # Get current timestamp
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        # Start building HTML
        html = f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Preliminary Analysis Report</title>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <style>
        {get_apple_style_css()}
    </style>
</head>
<body>
    <div class="container">
        <header class="header">
            <div class="header-content">
                <h1>📊 Preliminary Analysis Report{f" - {title}" if title else ""}</h1>
                <div class="metadata">
                    <span class="badge">Generated: {timestamp}</span>
                    <span class="badge">Columns: {len(self.analysis.cols)}</span>
                    <span class="badge">α = {self.analysis.alpha}</span>
                    <span class="badge">Total Observations: {self.analysis.df.height}, Unique Encounters: {self.analysis.df.select(pl.col(self.analysis.id_col).n_unique()).item()}</span>
                    <span class="badge">Plot Library: {self.analysis.plot_library}</span>
                </div>
            </div>
        </header>

        <main class="main-content">
            {self._generate_descriptive_statistics_section()}
            {self._generate_normality_check_section()}
            {self._generate_autocorrelation_section()}
            {self._generate_correlation_section()}
        </main>

        <footer class="footer">
            <p>Report generated by Imperfekt Analysis Framework</p>
        </footer>
    </div>

    <script>
        {get_javascript()}
    </script>
</body>
</html>
"""
        return html

    def _generate_descriptive_statistics_section(self) -> str:
        """Generates the descriptive statistics section."""
        if self.analysis.results.descriptive_stats.is_empty():
            return self._generate_empty_section(
                "📊 Descriptive Statistics", "No descriptive statistics available"
            )

        # Convert descriptive statistics to HTML table
        stats_table_html = dataframe_to_html_table(
            self.analysis.results.descriptive_stats, "Descriptive Statistics"
        )

        # Generate violin plots section
        violin_plots_html = ""
        if self.analysis.results.plots.violin:
            plots_content = []
            for col, plot in self.analysis.results.plots.violin.items():
                plot_html = fig_to_html(plot)
                plots_content.append(f"""
                <div class="plot-section">
                    <div class="plot-header" onclick="togglePlot(this)">
                        <h4>Violin Plot: {col}</h4>
                        <span class="plot-chevron">▼</span>
                    </div>
                    <div class="collapsible-plot">
                        {plot_html}
                    </div>
                </div>
                """)
            violin_plots_html = f"""
            <div class="subsection">
                <div class="subsection-header">
                    <h3>🎻 Plots</h3>
                    <span class="subsection-chevron">▼</span>
                </div>
                <div class="subsection-content">
                    {"".join(plots_content)}
                </div>
            </div>
            """

        return f"""
        <section class="section">
            <div class="section-header">
                <h2 class="section-title">📊 Descriptive Statistics</h2>
                <span class="chevron">▼</span>
            </div>
            <div class="section-content">
                <div class="info">
                    <strong>What this shows:</strong>
                    <p><em>High-level summary of each numeric column.</em></p>
                    <ul>
                        <li><em>Location & spread:</em> mean/median (central tendency) and std/IQR (variability) highlight skew and dispersion.</li>
                        <li><em>Extremes:</em> min/max and selected percentiles reveal tails and potential outliers.</li>
                        <li><em>Distribution shape:</em> violin plots show density across the range, exposing multimodality or heavy tails.</li>
                    </ul>
                </div>
                <div class="subsection">
                    <div class="subsection-header">
                        <h3>📋 Summary Statistics</h3>
                        <span class="subsection-chevron">▼</span>
                    </div>
                    <div class="subsection-content">
                        <div class="table-container">
                            {stats_table_html}
                        </div>
                    </div>
                </div>
                {violin_plots_html}
            </div>
        </section>
        """

    def _generate_normality_check_section(self) -> str:
        """Generates the normality tests section."""
        content_parts = []

        # Shapiro-Wilk test results
        if not self.analysis.results.shapiro_wilk.is_empty():
            shapiro_table_html = dataframe_to_html_table(
                self.analysis.results.shapiro_wilk, "Shapiro-Wilk Test Results"
            )
            content_parts.append(f"""
            <div class="subsection">
                <div class="subsection-header">
                    <h3>🧪 Shapiro-Wilk Normality Test</h3>
                    <span class="subsection-chevron">▼</span>
                </div>
                <div class="subsection-content">

                    <div class="info">
                        <strong>What this shows:</strong>
                        <p><em>Column-wise check for normality.</em></p>
                        <ul>
                            <li><em>Null hypothesis:</em> data are normally distributed.</li>
                            <li><em>Decision rule:</em> p &lt; α → reject normality; p ≥ α → no evidence against normality.</li>
                            <li><em>Implication:</em> non-normal variables may need transformation or non-parametric methods.</li>
                        </ul>
                    </div>

                    <div class="table-container">
                        {shapiro_table_html}
                    </div>
                </div>
            </div>
            """)

        # Multivariate normality results
        if not self.analysis.results.intervariable_normality.is_empty():
            mv_norm_table_html = dataframe_to_html_table(
                self.analysis.results.intervariable_normality,
                "Multivariate Normality Test Results",
            )
            content_parts.append(f"""
            <div class="subsection">
                <div class="subsection-header">
                    <h3>🔬 Multivariate Normality Test</h3>
                    <span class="subsection-chevron">▼</span>
                </div>
                <div class="subsection-content">
                    <div class="info">
                        <strong>What this shows:</strong>
                        <p><em>Joint normality across numeric columns.</em></p>
                        <ul>
                            <li><em>Null hypothesis:</em> the vector of variables is intervariable normal.</li>
                            <li><em>Decision rule:</em> p &lt; α → joint normality unlikely.</li>
                            <li><em>Implication:</em> affects techniques assuming intervariable normality.</li>
                        </ul>
                    </div>
                    <div class="table-container">
                        {mv_norm_table_html}
                    </div>
                </div>
            </div>
            """)

        # Q-Q plots
        if self.analysis.results.plots.qq_plot:
            plots_content = []
            for col, plot in self.analysis.results.plots.qq_plot.items():
                plot_html = fig_to_html(plot)
                plots_content.append(f"""
                <div class="plot-section">
                    <div class="plot-header" onclick="togglePlot(this)">
                        <h4>📈 Q-Q Plot: {col}</h4>
                        <span class="plot-chevron">▼</span>
                    </div>
                    <div class="collapsible-plot">
                        {plot_html}
                    </div>
                </div>
                """)
            content_parts.append(f"""
                <div class="subsection">
                    <div class="subsection-header">
                        <h3>📈 Q-Q Plots</h3>
                        <span class="subsection-chevron">▼</span>
                    </div>
                    <div class="subsection-content">

                        <div class="info">
                            <strong>What this shows:</strong>
                            <p><em>Visual comparison of sample quantiles vs. theoretical normal quantiles.</em></p>
                            <ul>
                                <li><em>Straight line:</em> data are broadly consistent with normality.</li>
                                <li><em>Curved pattern:</em> concave up → right-skew (long right tail), concave down → left-skew (long left tail).</li>
                                <li><em>Tail deviations:</em> points bending away at the ends indicate heavier or lighter tails than a normal distribution.</li>
                                <li><em>Practical use:</em> complements p-values by showing where and how the distribution departs from normality.</li>
                            </ul>
                        </div>
                        {"".join(plots_content)}
                    </div>
                </div>
                """)

        if not content_parts:
            return self._generate_empty_section(
                "🧪 Normality Tests", "No normality test results available"
            )

        content = "".join(content_parts)
        return f"""
        <section class="section">
            <div class="section-header">
                <h2 class="section-title">🧪 Normality Tests</h2>
                <span class="chevron">▼</span>
            </div>
            <div class="section-content">
                {content}
            </div>
        </section>
        """

    def _generate_autocorrelation_section(self) -> str:
        """Generates the autocorrelation section."""
        if not self.analysis.results.autocorrelation:
            return self._generate_empty_section(
                "🔄 Autocorrelation Analysis", "No autocorrelation results available"
            )

        content_parts = []

        # Autocorrelation plots
        if self.analysis.results.plots.autocorrelation_lag_plot:
            plots_content = []
            for (
                col,
                plot,
            ) in self.analysis.results.plots.autocorrelation_lag_plot.items():
                plot_html = fig_to_html(plot)
                plots_content.append(f"""
                <div class="plot-section">
                    <div class="plot-header" onclick="togglePlot(this)">
                        <h4>📈 Autocorrelation Plot: {col}</h4>
                        <span class="plot-chevron">▼</span>
                    </div>
                    <div class="collapsible-plot">
                        {plot_html}
                    </div>
                </div>
                """)
            content_parts.append(f"""
            <div class="subsection">
                <div class="subsection-header">
                    <h3>📈 Autocorrelation Plots</h3>
                    <span class="subsection-chevron">▼</span>
                </div>
                <div class="subsection-content">

                    <div class="info">
                        <strong>What this shows:</strong>
                        <p><em>Temporal dependence within each variable.</em></p>
                        <ul>
                            <li><em>Lag k &gt; 0:</em> positive values → persistence/clustering; negative → alternation/mean-reversion.</li>
                            <li><em>Seasonality:</em> repeating peaks at multiples of a period suggest cycles.</li>
                        </ul>
                    </div>
                    {"".join(plots_content)}
                </div>
            </div>
            """)

        if not content_parts:
            return self._generate_empty_section(
                "🔄 Autocorrelation Analysis", "No autocorrelation data available"
            )

        content = "".join(content_parts)
        return f"""
        <section class="section">
            <div class="section-header">
                <h2 class="section-title">🔄 Autocorrelation Analysis</h2>
                <span class="chevron">▼</span>
            </div>
            <div class="section-content">
                {content}
            </div>
        </section>
        """

    def _generate_correlation_section(self) -> str:
        """Generates the correlation section."""
        if self.analysis.results.correlation.is_empty():
            return self._generate_empty_section(
                "🔗 Correlation Analysis", "No correlation results available"
            )

        # Correlation matrix table
        corr_table_html = dataframe_to_html_table(
            self.analysis.results.correlation, "Correlation Matrix"
        )

        # Correlation heatmap
        heatmap_plot_html = ""
        if self.analysis.results.plots.correlation_heatmap:
            heatmap_plot_html = fig_to_html(self.analysis.results.plots.correlation_heatmap)

        return f"""
        <section class="section">
            <div class="section-header">
                <h2 class="section-title">🔗 Correlation Analysis</h2>
                <span class="chevron">▼</span>
            </div>
            <div class="section-content">
                <div class="subsection">
                    <div class="subsection-header">
                        <h3>📋 Correlation Matrix</h3>
                        <span class="subsection-chevron">▼</span>
                    </div>
                <div class="subsection-content">

                    <div class="info">
                        <strong>What this shows:</strong>
                        <p><em>Linear association between numeric variables (Pearson’s r: −1 to 1).</em></p>
                        <ul>
                            <li><em>Magnitude:</em> |r| close to 1 → strong linear relationship; near 0 → weak/no linear relationship.</li>
                            <li><em>Sign:</em> positive → move together; negative → move in opposite directions.</li>
                            <li><em>Heatmap:</em> quick scan for clusters/collinearity; use to guide feature selection or regularization.</li>
                        </ul>
                    </div>

                    <div class="table-container">
                        {corr_table_html}
                    </div>
                    <div class="plot-container">
                        {heatmap_plot_html}
                    </div>
                </div>
            </div>
        </section>
        """

    def _generate_empty_section(self, title: str, message: str) -> str:
        """Generates an empty section with a warning message."""
        return f"""
        <section class="section">
            <div class="section-header">
                <h2 class="section-title">{title}</h2>
                <span class="chevron">▼</span>
            </div>
            <div class="section-content">
                <div class="warning">
                    <p>{message}</p>
                </div>
            </div>
        </section>
        """
