"""Reads the JSONL audit trail generated by MoralStack's observability layer and
produces a human-readable Markdown report with one section per request.
"""

from __future__ import annotations

import argparse
import json
import os
from collections import defaultdict
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Export MoralStack audit JSONL events to Markdown")
    parser.add_argument("--input", type=str, default=None, help="Path to an input JSONL file")
    parser.add_argument("--output", type=str, default="audit_report.md", help="Path to output Markdown report")
    return parser.parse_args()


def resolve_latest_jsonl(path_dir: Path) -> Path | None:
    candidates = [p for p in path_dir.glob("*.jsonl") if p.is_file()]
    if not candidates:
        return None
    return max(candidates, key=lambda p: p.stat().st_mtime)


def to_iso_utc(timestamp_ms: int | None) -> str:
    if not timestamp_ms:
        return "-"
    dt = datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc)
    return dt.isoformat().replace("+00:00", "Z")


def time_of_day(timestamp_ms: int | None) -> str:
    if not timestamp_ms:
        return "--:--:--"
    dt = datetime.fromtimestamp(timestamp_ms / 1000, tz=timezone.utc)
    return dt.strftime("%H:%M:%S")


def extract_summary(events: list[dict[str, Any]]) -> dict[str, Any]:
    final_action = "-"
    risk_score = "-"
    overlay = "-"
    for event in sorted(events, key=lambda e: e.get("timestamp_ms") or 0):
        payload = event.get("payload") or {}
        if isinstance(payload, dict):
            if payload.get("final_action"):
                final_action = str(payload.get("final_action"))
            if payload.get("domain_overlay"):
                overlay = str(payload.get("domain_overlay"))
            if payload.get("risk_score") is not None:
                try:
                    risk_score = "{:.2f}".format(float(payload.get("risk_score")))
                except (TypeError, ValueError):
                    risk_score = str(payload.get("risk_score"))
    first_ts = min((e.get("timestamp_ms") for e in events if e.get("timestamp_ms") is not None), default=None)
    return {
        "timestamp": to_iso_utc(first_ts),
        "final_action": final_action,
        "risk_score": risk_score,
        "overlay": overlay,
    }


def main() -> None:
    args = parse_args()

    if args.input:
        input_path = Path(args.input)
    else:
        jsonl_dir = Path(os.getenv("MORALSTACK_JSONL_DIR", "logs/observability"))
        latest = resolve_latest_jsonl(jsonl_dir)
        if latest is None:
            print(
                "No JSONL file found. Set MORALSTACK_OBSERVABILITY_MODE=file_only and MORALSTACK_JSONL_DIR, "
                "then run examples/quickstart.py."
            )
            return
        input_path = latest

    if not input_path.exists():
        print(
            "Input file not found: {}. Set MORALSTACK_OBSERVABILITY_MODE=file_only and MORALSTACK_JSONL_DIR, "
            "then run examples/quickstart.py.".format(input_path)
        )
        return

    grouped: dict[str, list[dict[str, Any]]] = defaultdict(list)

    with input_path.open("r", encoding="utf-8") as handle:
        for line_number, line in enumerate(handle, start=1):
            stripped = line.strip()
            if not stripped:
                continue
            try:
                event = json.loads(stripped)
            except json.JSONDecodeError:
                print("Skipping malformed JSON line {}".format(line_number))
                continue

            request_id = event.get("request_id")
            session_id = event.get("session_id")
            bucket = str(request_id or session_id or "unknown")
            grouped[bucket].append(event)

    output_path = Path(args.output)
    with output_path.open("w", encoding="utf-8") as out:
        out.write("# MoralStack Audit Report\n\n")
        out.write("Source file: `{}`\n\n".format(input_path))

        for key in sorted(grouped.keys()):
            events = sorted(grouped[key], key=lambda e: e.get("timestamp_ms") or 0)
            summary = extract_summary(events)

            out.write("## Request {}\n\n".format(key))
            out.write("**Timestamp:** {}\n".format(summary["timestamp"]))
            out.write("**Final action:** {}\n".format(summary["final_action"]))
            out.write("**Risk score:** {}\n".format(summary["risk_score"]))
            out.write("**Overlay:** {}\n\n".format(summary["overlay"]))
            out.write("### Timeline\n")

            for event in events:
                out.write(
                    "- {} — {}\n".format(
                        time_of_day(event.get("timestamp_ms")),
                        event.get("event_type", "unknown"),
                    )
                )

            out.write("\n")

    print("Markdown report written to {}".format(output_path))


if __name__ == "__main__":
    main()
