"""HTML report generator."""

from __future__ import annotations

from datetime import datetime
from pathlib import Path
from typing import Any

from jinja2 import Environment, FileSystemLoader, PackageLoader, select_autoescape

from src.kpi.tree import KPITree
from src.kpi.analyzer import KPIAnalyzer, BottleneckInfo
from src.ai.analyzer import AnalysisResult


class HTMLReportGenerator:
    """Generate HTML reports from KPI analysis."""

    def __init__(self, template_dir: str | Path | None = None):
        """Initialize generator.

        Args:
            template_dir: Optional custom template directory.
        """
        if template_dir:
            self.env = Environment(
                loader=FileSystemLoader(str(template_dir)),
                autoescape=select_autoescape(["html", "xml"]),
            )
        else:
            # Use default embedded templates
            self.env = Environment(
                loader=FileSystemLoader(Path(__file__).parent.parent.parent / "templates"),
                autoescape=select_autoescape(["html", "xml"]),
            )

        # Register custom filters
        self.env.filters["format_number"] = self._format_number
        self.env.filters["format_percent"] = self._format_percent
        self.env.filters["status_class"] = self._status_class
        self.env.filters["trend_icon"] = self._trend_icon

    def generate(
        self,
        tree: KPITree,
        analysis_results: dict[str, AnalysisResult],
        period: str,
        output_path: str | Path,
        title: str = "PlanitAI KPI Report",
    ) -> Path:
        """Generate HTML report.

        Args:
            tree: KPI tree with calculated values.
            analysis_results: AI analysis results.
            period: Reporting period.
            output_path: Output directory or file path.
            title: Report title.

        Returns:
            Path to generated HTML file.
        """
        output_path = Path(output_path)

        # Prepare output file
        if output_path.is_dir():
            output_file = output_path / f"report_{period.replace(' ', '_')}.html"
        else:
            output_file = output_path
            output_path = output_path.parent

        output_path.mkdir(parents=True, exist_ok=True)

        # Prepare context
        analyzer = KPIAnalyzer(tree)
        context = self._prepare_context(tree, analyzer, analysis_results, period, title)

        # Render template
        template = self.env.get_template("report.html")
        html = template.render(**context)

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

        return output_file

    def _prepare_context(
        self,
        tree: KPITree,
        analyzer: KPIAnalyzer,
        analysis_results: dict[str, AnalysisResult],
        period: str,
        title: str,
    ) -> dict[str, Any]:
        """Prepare template context.

        Args:
            tree: KPI tree.
            analyzer: KPI analyzer.
            analysis_results: AI analysis results.
            period: Reporting period.
            title: Report title.

        Returns:
            Template context dictionary.
        """
        # Get KGI summary
        kgi_summary = analyzer.get_kgi_summary()

        # Get performance data
        performance = analyzer.get_performance_summary()

        # Get bottlenecks
        bottlenecks = analyzer.find_bottlenecks()

        # Get category summary
        category_summary = analyzer.get_category_summary()

        # Extract AI insights
        executive = analysis_results.get("executive_summary")
        trends = analysis_results.get("trends")
        bottleneck_analysis = analysis_results.get("bottlenecks")

        return {
            "title": title,
            "period": period,
            "generated_at": datetime.now().strftime("%Y-%m-%d %H:%M"),
            # KGI
            "kgi": kgi_summary,
            # Tree
            "tree": tree.to_dict(),
            "tree_text": tree.to_text(),
            # Performance
            "performance": [p.to_dict() for p in performance],
            # Bottlenecks
            "bottlenecks": [b.to_dict() for b in bottlenecks[:5]],
            "bottleneck_count": len(bottlenecks),
            # Categories
            "categories": category_summary,
            # AI Analysis
            "executive_summary": executive.data if executive else {},
            "trend_analysis": trends.data if trends else {},
            "bottleneck_insights": bottleneck_analysis.data if bottleneck_analysis else {},
            # Summaries
            "ai_summary": executive.summary if executive else "",
        }

    @staticmethod
    def _format_number(value: float | None, decimals: int = 0) -> str:
        """Format number with thousands separator."""
        if value is None:
            return "-"
        if decimals == 0:
            return f"{value:,.0f}"
        return f"{value:,.{decimals}f}"

    @staticmethod
    def _format_percent(value: float | None, decimals: int = 1) -> str:
        """Format as percentage."""
        if value is None:
            return "-"
        return f"{value:.{decimals}f}%"

    @staticmethod
    def _status_class(achievement_rate: float | None) -> str:
        """Get CSS class based on achievement rate."""
        if achievement_rate is None:
            return "neutral"
        if achievement_rate >= 100:
            return "success"
        if achievement_rate >= 80:
            return "warning"
        return "danger"

    @staticmethod
    def _trend_icon(trend: str) -> str:
        """Get icon for trend."""
        icons = {
            "improving": "↑",
            "stable": "→",
            "declining": "↓",
        }
        return icons.get(trend, "→")


def generate_embedded_css() -> str:
    """Generate embedded CSS for reports."""
    return """
    :root {
        --primary: #2563eb;
        --success: #22c55e;
        --warning: #f59e0b;
        --danger: #ef4444;
        --neutral: #6b7280;
        --bg: #f8fafc;
        --card-bg: #ffffff;
        --text: #1e293b;
        --text-secondary: #64748b;
        --border: #e2e8f0;
    }

    * { box-sizing: border-box; margin: 0; padding: 0; }

    body {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        background: var(--bg);
        color: var(--text);
        line-height: 1.6;
    }

    .container { max-width: 1200px; margin: 0 auto; padding: 2rem; }

    .header {
        background: var(--primary);
        color: white;
        padding: 2rem;
        margin-bottom: 2rem;
        border-radius: 0.5rem;
    }

    .header h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
    .header .period { opacity: 0.9; }

    .grid { display: grid; gap: 1.5rem; }
    .grid-2 { grid-template-columns: repeat(2, 1fr); }
    .grid-3 { grid-template-columns: repeat(3, 1fr); }
    .grid-4 { grid-template-columns: repeat(4, 1fr); }

    @media (max-width: 768px) {
        .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
    }

    .card {
        background: var(--card-bg);
        border-radius: 0.5rem;
        padding: 1.5rem;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        border: 1px solid var(--border);
    }

    .card-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 1rem;
        padding-bottom: 0.75rem;
        border-bottom: 1px solid var(--border);
    }

    .card-title { font-size: 1rem; font-weight: 600; }

    .metric { text-align: center; padding: 1rem; }
    .metric-value { font-size: 2rem; font-weight: 700; }
    .metric-label { color: var(--text-secondary); font-size: 0.875rem; }

    .success { color: var(--success); }
    .warning { color: var(--warning); }
    .danger { color: var(--danger); }
    .neutral { color: var(--neutral); }

    .badge {
        display: inline-block;
        padding: 0.25rem 0.5rem;
        border-radius: 0.25rem;
        font-size: 0.75rem;
        font-weight: 500;
    }

    .badge-success { background: #dcfce7; color: #166534; }
    .badge-warning { background: #fef3c7; color: #92400e; }
    .badge-danger { background: #fee2e2; color: #991b1b; }

    table { width: 100%; border-collapse: collapse; }
    th, td { padding: 0.75rem; text-align: left; border-bottom: 1px solid var(--border); }
    th { font-weight: 600; color: var(--text-secondary); font-size: 0.875rem; }

    .progress-bar {
        height: 8px;
        background: var(--border);
        border-radius: 4px;
        overflow: hidden;
    }

    .progress-fill {
        height: 100%;
        border-radius: 4px;
        transition: width 0.3s;
    }

    .highlight-box {
        padding: 1rem;
        border-radius: 0.5rem;
        margin-bottom: 1rem;
    }

    .highlight-positive { background: #dcfce7; border-left: 4px solid var(--success); }
    .highlight-negative { background: #fee2e2; border-left: 4px solid var(--danger); }
    .highlight-neutral { background: #f1f5f9; border-left: 4px solid var(--neutral); }

    .tree-node { margin-left: 1.5rem; padding: 0.5rem 0; }
    .tree-node-kgi { font-weight: 700; font-size: 1.1rem; }
    .tree-node-kpi { font-weight: 500; }
    .tree-node-input { color: var(--text-secondary); }

    .footer {
        text-align: center;
        padding: 2rem;
        color: var(--text-secondary);
        font-size: 0.875rem;
    }
    """
