"""Markdown post-mortem renderer.

Turns a DiagnosisResult into a structured incident report that can be
shared in GitHub, Notion, Confluence, or Google Docs.
"""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime, timezone
from typing import Any

from autopsy import PROMPT_VERSION, __version__
from autopsy.ai.models import DiagnosisResult  # noqa: TC001 — used at runtime


@dataclass
class PostMortemMetadata:
    """Optional contextual data for the post-mortem footer."""

    provider: str | None = None
    model: str | None = None
    log_groups: list[str] | None = None
    time_window: int | None = None
    duration_s: float | None = None


def _now_iso_utc() -> str:
    return datetime.now(tz=timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")


def _escape_table_cell(text: str) -> str:
    """Escape characters that would break markdown tables."""
    return text.replace("|", "\\|")


class PostMortemRenderer:
    """Generate a markdown post-mortem document from a diagnosis."""

    def render(
        self,
        result: DiagnosisResult,
        output_path: Any | None = None,
        *,
        metadata: PostMortemMetadata | None = None,
    ) -> str:
        """
        Generate markdown post-mortem.

        If output_path provided, write to file and return path as string.
        If None, return the markdown string.
        """
        md = self._build_markdown(result, metadata or PostMortemMetadata())
        if output_path is not None:
            output_path.parent.mkdir(parents=True, exist_ok=True)
            output_path.write_text(md, encoding="utf-8")
            return str(output_path)
        return md

    def _build_markdown(self, result: DiagnosisResult, meta: PostMortemMetadata) -> str:
        rc = result.root_cause
        cd = result.correlated_deploy
        sf = result.suggested_fix

        iso_date = _now_iso_utc()

        # Timeline table
        if result.timeline:
            timeline_rows = [
                f"| {_escape_table_cell(ev.time)} | {_escape_table_cell(ev.event)} |"
                for ev in result.timeline
            ]
        else:
            timeline_rows = ["| — | No timeline events captured |"]

        # Evidence
        if rc.evidence:
            evidence_lines = [f"- {item}" for item in rc.evidence]
        else:
            evidence_lines = ["- No explicit evidence items captured; review logs manually."]

        # Contributing factors — team will refine these later.
        contributing_factors = [
            "- Lack of null-check / validation on relevant code paths (to be confirmed).",
            "- To be determined by team review.",
        ]

        # Correlated deploy section
        correlated_lines: list[str] = []
        if cd.commit_sha or cd.author or cd.pr_title or cd.changed_files:
            if cd.commit_sha:
                correlated_lines.append(f"- **Commit:** {cd.commit_sha}")
            if cd.author:
                correlated_lines.append(f"- **Author:** {cd.author}")
            if cd.pr_title:
                correlated_lines.append(f"- **PR/Description:** {cd.pr_title}")
            if cd.changed_files:
                correlated_lines.append("- **Files Changed:**")
                for f in cd.changed_files:
                    correlated_lines.append(f"  - {f}")
            # Heuristic for deploy time: first event mentioning "deploy"
            deploy_time = next(
                (ev.time for ev in result.timeline if "deploy" in ev.event.lower()),
                None,
            )
            if deploy_time:
                correlated_lines.append(f"- **Deployed:** {deploy_time}")
        else:
            correlated_lines.append(
                "No specific code change was correlated with this incident. "
                "The root cause may be infrastructure, dependency, or traffic related."
            )

        # Metadata footer values
        autopsy_version = __version__
        provider = meta.provider or "N/A"
        model = meta.model or "N/A"
        log_groups = ", ".join(meta.log_groups) if meta.log_groups else "N/A"
        time_window = f"{meta.time_window}" if meta.time_window is not None else "N/A"
        duration_val = f"{meta.duration_s:.2f}s" if meta.duration_s is not None else "N/A"

        lines: list[str] = []
        lines.append("# Incident Post-Mortem Report")
        lines.append("")
        lines.append(f"**Generated by:** AUTOPSY CLI v{autopsy_version}")
        lines.append(f"**Date:** {iso_date}")
        lines.append("**Status:** Auto-generated — review and edit before sharing")
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Summary")
        lines.append("")
        lines.append(rc.summary)
        lines.append("")
        lines.append(f"- **Category:** {rc.category}")
        lines.append(f"- **Confidence:** {rc.confidence * 100:.0f}%")
        lines.append("- **Detection Method:** Automated diagnosis via AUTOPSY CLI")
        lines.append("")
        if len(result.sources) > 1:
            lines.append("## Data Sources")
            lines.append("")
            lines.append("| Source | Type | Entries |")
            lines.append("|--------|------|---------|")
            for src in result.sources:
                lines.append(
                    f"| {src.name.title()} | {src.data_type.title()} | {src.entry_count} |"
                )
            lines.append("")

        lines.append("---")
        lines.append("")
        lines.append("## Timeline")
        lines.append("")
        lines.append("| Time (UTC) | Event |")
        lines.append("|------------|-------|")
        lines.extend(timeline_rows)
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Root Cause Analysis")
        lines.append("")
        lines.append("### What Happened")
        lines.append("")
        lines.append(rc.summary)
        lines.append("")
        lines.append("### Evidence")
        lines.append("")
        lines.extend(evidence_lines)
        lines.append("")
        lines.append("### Contributing Factors")
        lines.append("")
        lines.extend(contributing_factors)
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Correlated Code Change")
        lines.append("")
        lines.extend(correlated_lines)
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Resolution")
        lines.append("")
        lines.append("### Immediate Actions Taken")
        lines.append("")
        lines.append(f"- [ ] {sf.immediate}")
        lines.append("")
        lines.append("### Long-Term Fixes Required")
        lines.append("")
        lines.append(f"- [ ] {sf.long_term}")
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Action Items")
        lines.append("")
        lines.append("| # | Action | Owner | Due Date | Status |")
        lines.append("|---|--------|-------|----------|--------|")
        lines.append(f"| 1 | {sf.immediate} | TBD | TBD | ⬜ Open |")
        lines.append(f"| 2 | {sf.long_term} | TBD | TBD | ⬜ Open |")
        lines.append(
            "| 3 | Review monitoring/alerting for this failure mode | "
            "TBD | TBD | ⬜ Open |"
        )
        lines.append("| 4 | Update runbooks if applicable | TBD | TBD | ⬜ Open |")
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Lessons Learned")
        lines.append("")
        lines.append("### What Went Well")
        lines.append("")
        lines.append("- Incident was detected via automated monitoring")
        lines.append(
            f"- Root cause was identified using AUTOPSY CLI in {duration_val}"
        )
        lines.append("")
        lines.append("### What Could Be Improved")
        lines.append("")
        lines.append("- *[Team to fill in during post-mortem review]*")
        lines.append("")
        lines.append("### Process Changes")
        lines.append("")
        lines.append("- *[Team to fill in during post-mortem review]*")
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append("## Appendix")
        lines.append("")
        lines.append("### Diagnosis Metadata")
        lines.append("")
        lines.append(f"- **AUTOPSY Version:** {autopsy_version}")
        lines.append(f"- **Prompt Version:** {result.prompt_version or PROMPT_VERSION}")
        lines.append(f"- **AI Provider:** {provider}")
        lines.append(f"- **Model:** {model}")
        lines.append(f"- **Log Groups Queried:** {log_groups}")
        lines.append(f"- **Time Window:** {time_window} minutes")
        lines.append(f"- **Diagnosis Duration:** {duration_val}")
        lines.append("")
        lines.append("---")
        lines.append("")
        lines.append(
            "*This report was auto-generated by "
            "[AUTOPSY CLI](https://github.com/zeelapatel/autopsy). "
            "Review all findings before sharing. AI-generated analysis may contain inaccuracies.*"
        )

        return "\n".join(lines)

    def _generate_filename(self, result: DiagnosisResult) -> str:
        """Generate filename: postmortem-YYYY-MM-DD-{category}-{short_summary}.md"""
        rc = result.root_cause
        today = datetime.now(tz=timezone.utc).date().isoformat()
        category = rc.category.lower().replace(" ", "-")
        summary = rc.summary.lower()

        safe_summary_chars: list[str] = []
        for ch in summary:
            if ch.isalnum():
                safe_summary_chars.append(ch)
            elif ch.isspace() or ch in "-_":
                safe_summary_chars.append("-")
        summary_slug = "".join(safe_summary_chars).strip("-")
        if len(summary_slug) > 40:
            summary_slug = summary_slug[:40].rstrip("-")

        if not summary_slug:
            summary_slug = "incident"

        return f"postmortem-{today}-{category}-{summary_slug}.md"

