"""
Report — HTML, Markdown, and JSON report generation with Jinja2 templates.
"""

from __future__ import annotations

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

import pandas as pd
from jinja2 import Environment, BaseLoader

from bizanalyticsai.core.dataframe import BizFrame

# ── HTML template ─────────────────────────────────────────────────────────────
_HTML_TEMPLATE = """<!DOCTYPE html>
<html lang="pt-BR">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{ title }}</title>
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
           background: #0f0e17; color: #e0dff0; line-height: 1.6; padding: 32px; }
    h1 { font-size: 2rem; font-weight: 900; color: #a78bfa; margin-bottom: 6px; }
    h2 { font-size: 1.2rem; font-weight: 700; color: #c4b5fd; margin: 28px 0 12px; }
    h3 { font-size: 1rem; font-weight: 600; color: #8b5cf6; margin: 16px 0 8px; }
    .meta { font-size: 0.8rem; color: #6b7280; margin-bottom: 32px; }
    .card { background: rgba(139,92,246,0.06); border: 1px solid rgba(139,92,246,0.2);
            border-radius: 12px; padding: 20px 24px; margin-bottom: 20px; }
    .kpi-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; margin-bottom: 24px; }
    .kpi { background: rgba(255,255,255,0.04); border-radius: 8px; padding: 14px 16px; }
    .kpi-label { font-size: 0.7rem; color: #9ca3af; text-transform: uppercase; letter-spacing: .06em; margin-bottom: 4px; }
    .kpi-value { font-size: 1.4rem; font-weight: 800; color: #a78bfa; }
    table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 0.85rem; }
    th { background: rgba(139,92,246,0.15); color: #c4b5fd; text-align: left;
         padding: 8px 12px; font-size: 0.75rem; text-transform: uppercase; letter-spacing: .05em; }
    td { padding: 7px 12px; border-bottom: 1px solid rgba(255,255,255,0.04); color: #d1d5db; }
    tr:hover td { background: rgba(255,255,255,0.03); }
    .badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.7rem; font-weight: 600; }
    .badge-green  { background: rgba(52,211,153,0.15); color: #34d399; }
    .badge-yellow { background: rgba(245,158,11,0.15); color: #f59e0b; }
    .badge-red    { background: rgba(239,68,68,0.15);  color: #ef4444; }
    footer { margin-top: 48px; font-size: 0.75rem; color: #4b5563; text-align: center; }
  </style>
</head>
<body>
  <h1>{{ title }}</h1>
  <p class="meta">Generated by BizAnalyticsAI {{ version }} &nbsp;|&nbsp; {{ generated_at }}</p>

  {% if kpis %}
  <div class="kpi-grid">
    {% for kpi in kpis %}
    <div class="kpi">
      <div class="kpi-label">{{ kpi.label }}</div>
      <div class="kpi-value">{{ kpi.value }}</div>
    </div>
    {% endfor %}
  </div>
  {% endif %}

  {% for section in sections %}
  <div class="card">
    <h2>{{ section.title }}</h2>
    {% if section.description %}<p style="font-size:.85rem;color:#9ca3af;margin-bottom:12px">{{ section.description }}</p>{% endif %}

    {% if section.type == "table" and section.data %}
    <table>
      <thead>
        <tr>{% for col in section.columns %}<th>{{ col }}</th>{% endfor %}</tr>
      </thead>
      <tbody>
        {% for row in section.data %}
        <tr>{% for col in section.columns %}<td>{{ row.get(col, '') }}</td>{% endfor %}</tr>
        {% endfor %}
      </tbody>
    </table>
    {% endif %}

    {% if section.type == "text" %}
    <p style="font-size:.9rem;color:#d1d5db;white-space:pre-wrap">{{ section.content }}</p>
    {% endif %}

    {% if section.type == "kpis" %}
    <div class="kpi-grid">
      {% for kpi in section.kpis %}
      <div class="kpi">
        <div class="kpi-label">{{ kpi.label }}</div>
        <div class="kpi-value">{{ kpi.value }}</div>
      </div>
      {% endfor %}
    </div>
    {% endif %}
  </div>
  {% endfor %}

  <footer>
    BizAnalyticsAI &copy; {{ year }} &mdash; bizanalyticsai.com.br
  </footer>
</body>
</html>
"""


def html(
    df: pd.DataFrame | None = None,
    title: str = "BizAnalyticsAI Report",
    kpis: list[dict] | None = None,
    sections: list[dict] | None = None,
    output: str | Path | None = None,
) -> str:
    """
    Generate an HTML report.

    Args:
        df:       Optional DataFrame to include as a table section.
        title:    Report title.
        kpis:     List of {label, value} dicts for the KPI grid.
        sections: List of section dicts. Each section has:
                  - title (str)
                  - type: 'table' | 'text' | 'kpis'
                  - For 'table': data (list[dict]), columns (list[str])
                  - For 'text': content (str)
                  - For 'kpis': kpis (list[{label, value}])
        output:   If set, write HTML to this file path.

    Returns:
        HTML string.
    """
    all_sections = list(sections or [])

    if df is not None and len(df) > 0:
        all_sections.append({
            "title":   "Data",
            "type":    "table",
            "columns": list(df.columns),
            "data":    df.head(200).to_dict(orient="records"),
        })

    env = Environment(loader=BaseLoader())
    tpl = env.from_string(_HTML_TEMPLATE)
    rendered = tpl.render(
        title=title,
        version="1.0.0",
        generated_at=datetime.now().strftime("%Y-%m-%d %H:%M"),
        year=datetime.now().year,
        kpis=kpis or [],
        sections=all_sections,
    )

    if output:
        Path(output).write_text(rendered, encoding="utf-8")

    return rendered


def markdown(
    df: pd.DataFrame | None = None,
    title: str = "BizAnalyticsAI Report",
    sections: list[dict] | None = None,
    output: str | Path | None = None,
) -> str:
    """
    Generate a Markdown report.

    Args:
        df:       Optional DataFrame shown as a Markdown table.
        title:    Report title.
        sections: List of {title, content} dicts.
        output:   If set, write to file.

    Returns:
        Markdown string.
    """
    lines = [
        f"# {title}",
        f"\n_Generated by BizAnalyticsAI 1.0.0 — {datetime.now().strftime('%Y-%m-%d %H:%M')}_\n",
    ]

    for section in (sections or []):
        lines.append(f"## {section['title']}\n")
        if section.get("content"):
            lines.append(str(section["content"]) + "\n")

    if df is not None and len(df) > 0:
        lines.append("## Data\n")
        lines.append(df.head(100).to_markdown(index=False))
        lines.append("")

    result = "\n".join(lines)
    if output:
        Path(output).write_text(result, encoding="utf-8")
    return result


def to_json(data: Any, output: str | Path | None = None, indent: int = 2) -> str:
    """
    Serialize data to JSON.

    Handles DataFrames, BizFrames, numpy types, and nested structures.
    """
    def _default(obj):
        if isinstance(obj, (pd.DataFrame, BizFrame)):
            return obj.to_dict(orient="records")
        if isinstance(obj, pd.Series):
            return obj.tolist()
        if hasattr(obj, "item"):
            return obj.item()
        if hasattr(obj, "__dict__"):
            return obj.__dict__
        return str(obj)

    result = json.dumps(data, default=_default, indent=indent, ensure_ascii=False)
    if output:
        Path(output).write_text(result, encoding="utf-8")
    return result


def summary_report(
    df: pd.DataFrame,
    title: str = "Business Data Summary",
    output: str | Path | None = None,
) -> str:
    """
    Auto-generate a comprehensive HTML summary report from a DataFrame.

    Includes: shape info, descriptive stats, missing values, top values.
    """
    from bizanalyticsai.stats.descriptive import describe
    from bizanalyticsai.core.dataframe import BizFrame

    bf  = BizFrame(df)
    desc = describe(df)
    qual = bf.quality()

    kpis_list = [
        {"label": "Total Rows",       "value": f"{len(df):,}"},
        {"label": "Total Columns",    "value": str(len(df.columns))},
        {"label": "Numeric Columns",  "value": str(len(desc.numeric_cols))},
        {"label": "Categorical Cols", "value": str(len(desc.cat_cols))},
        {"label": "Missing Values",   "value": f"{int(df.isna().sum().sum()):,}"},
        {"label": "Duplicate Rows",   "value": f"{int(df.duplicated().sum()):,}"},
    ]

    sections = [
        {
            "title":       "Data Quality",
            "description": "Per-column quality flags",
            "type":        "table",
            "columns":     list(qual.columns),
            "data":        qual.to_dict(orient="records"),
        },
        {
            "title":   "Descriptive Statistics",
            "type":    "table",
            "columns": list(desc.summary.columns),
            "data":    desc.summary.reset_index().rename(columns={"index": "column"}).to_dict(orient="records"),
        },
    ]

    if desc.insights:
        sections.append({
            "title":   "Insights",
            "type":    "text",
            "content": "\n".join(f"• {i}" for i in desc.insights),
        })

    return html(title=title, kpis=kpis_list, sections=sections, output=output)
