"""Premium Markdown Report Generator with ASCII Charts and Insights."""

from __future__ import annotations
from datetime import datetime
from pathlib import Path
from promptforge.store.repositories import RunRepository, ScoreRepository, CaseResultRepository
from promptforge.eval.aggregations import aggregate_run_scores, p95_latency, generate_ascii_bar


class MarkdownReporter:
    def __init__(self) -> None:
        self.run_repo = RunRepository()
        self.score_repo = ScoreRepository()
        self.case_repo = CaseResultRepository()

    def generate(self, run_id: str, out_path: str | None = None) -> str:
        run = self.run_repo.get_run(run_id)
        if not run:
            raise ValueError(f"Run not found: {run_id}")

        scores = self.score_repo.get_by_run(run_id)
        cases = self.case_repo.get_by_run(run_id)
        agg = aggregate_run_scores(scores)
        latencies = [c["latency_ms"] for c in cases]

        if not out_path:
            out_path = f"report_{run_id[:8]}.md"

        # FIX #5: protecção contra divisão por zero se latencies estiver vazio
        mean_lat = sum(latencies) / len(latencies) if latencies else 0.0
        p95 = p95_latency(latencies) if latencies else 0.0

        lines = [
            "# 🛠️ PromptForge Evaluation Report",
            f"> Generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
            "",
            "## 📊 Executive Summary",
            "| Metadata | Value |",
            "| :--- | :--- |",
            f"| **Run ID** | `{run_id}` |",
            f"| **Prompt** | `{run['prompt_id']}` (v{run['prompt_version']}) |",
            f"| **Dataset** | `{run['dataset_id']}` |",
            f"| **Model** | `{run['model']}` |",
            f"| **Provider** | `{run['provider'].upper()}` |",
            "",
            "---",
            "",
            "## 📈 Performance Metrics",
            "",
            "### Score Breakdown",
            "```text",
        ]

        for ev, stats in agg.items():
            bar = generate_ascii_bar(stats['mean'])
            lines.append(f"{ev:15} | {bar} | {stats['mean']:.3f}")

        lines += [
            "```",
            "",
            "| Metric | Value | Status |",
            "| :--- | :--- | :--- |",
            f"| **Total Cases** | {run['total_cases']} | - |",
            f"| **Total Tokens** | {run['total_tokens']} | - |",
            f"| **Mean Latency** | {mean_lat:.0f} ms | {'✅ Fast' if mean_lat < 1000 else '⚠️ Slow'} |",
            f"| **P95 Latency** | {p95:.0f} ms | - |",
            "",
            "---",
            "",
            "## 🔍 Detailed Analysis",
            "",
            "### ❌ Top Failures & Regressions",
        ]

        failures = sorted([s for s in scores if s["score"] < 0.8], key=lambda x: x["score"])
        if failures:
            lines.append("| Case ID | Evaluator | Score | Rationale |")
            lines.append("| :--- | :--- | :--- | :--- |")
            for f in failures[:10]:
                rationale = (f['rationale'] or "No rationale provided").replace("\n", " ")
                lines.append(f"| `{f['case_id']}` | {f['evaluator']} | **{f['score']:.2f}** | {rationale} |")
        else:
            lines.append("✅ **No critical failures detected in this run.**")

        lines += [
            "",
            "### 💡 Automated Insights",
        ]

        if any(s['mean'] < 1.0 for s in agg.values()):
            lines.append("- 📉 **Quality Alert:** Some evaluators scored below 1.0. Check the failures table for edge cases.")
        if p95 > 2000:
            lines.append("- 🐢 **Latency Alert:** P95 latency is high. Consider optimizing the prompt length or switching models.")
        if run['total_tokens'] > 5000:
            lines.append("- 💸 **Cost Warning:** High token usage detected. Review if the prompt template can be more concise.")

        lines += [
            "",
            "### 🛠️ Suggested Improvements",
            "1. **Refine Constraints:** If `json_validity` is high but `field_match` is low, clarify the expected values in the prompt system message.",
            "2. **Few-Shotting:** Add 2-3 examples of the failing cases to the prompt template to guide the model.",
            "3. **Schema Enforcement:** Use structured output parameters if the provider supports it to guarantee 100% schema match.",
            "",
            "---",
            "*Generated by [PromptForge](https://github.com/MPrazeres-1983/promptforge) — Minimalist LLMOps for Engineers.*"
        ]

        content = "\n".join(lines)
        Path(out_path).write_text(content, encoding="utf-8")
        return out_path
