"""Report generation for Unworldly.

Generates terminal and markdown security reports from recorded sessions,
including integrity verification and ISO 42001 compliance sections.
"""

from __future__ import annotations

from datetime import datetime

from .display import banner, verify_display
from .integrity import verify_session
from .session import load_session
from .types import Session, WatchEvent


def _group_by_risk(events: list[WatchEvent]) -> dict[str, list[WatchEvent]]:
    """Group events by their risk level."""
    result: dict[str, list[WatchEvent]] = {}
    for event in events:
        risk_val = event.risk.value if hasattr(event.risk, "value") else event.risk
        if risk_val not in result:
            result[risk_val] = []
        result[risk_val].append(event)
    return result


def _format_time(iso_string: str) -> str:
    """Format an ISO timestamp as HH:MM:SS."""
    dt = datetime.fromisoformat(iso_string.replace("Z", "+00:00"))
    return dt.strftime("%H:%M:%S")


def _generate_markdown(session: Session) -> str:
    """Generate a markdown security report from a session."""
    summary = session.summary
    events = session.events
    start_date = datetime.fromisoformat(session.start_time.replace("Z", "+00:00")).strftime("%c")
    end_date = (
        datetime.fromisoformat(session.end_time.replace("Z", "+00:00")).strftime("%c") if session.end_time else "N/A"
    )

    danger_events = [e for e in events if e.risk.value == "danger"]
    caution_events = [e for e in events if e.risk.value == "caution"]

    # Verify integrity for compliance section
    integrity = verify_session(session)

    agent_row = ""
    if session.agent:
        agent_row = f"| Agent | {session.agent.name} ({session.agent.detected_via}) |\n"

    integrity_issues = ""
    if integrity.errors:
        issues = "\n".join(f"- {e}" for e in integrity.errors)
        integrity_issues = f"\n**Issues:**\n{issues}\n"

    md = f"""# Unworldly Security Report

> Generated by [Unworldly](https://github.com/DilawarShafiq/unworldly) — The Flight Recorder for AI Agents
> ISO 42001 Compliant Audit Trail

## Session Overview

| Field | Value |
|-------|-------|
| Session ID | `{session.id}` |
| Version | `{session.version}` |
| Directory | `{session.directory}` |
| Started | {start_date} |
| Ended | {end_date} |
| Total Events | {summary.total_events} |
| Risk Score | **{summary.risk_score}/10** |
{agent_row}
## Integrity Verification

| Check | Status |
|-------|--------|
| Hash Chain | {integrity.valid_events}/{integrity.total_events} events verified |
| Session Seal | {"Valid" if integrity.session_hash_valid else "Invalid or missing"} |
| Overall | {"**PASSED** — No tampering detected" if integrity.valid else "**FAILED** — Possible tampering"} |
{integrity_issues}
## Risk Breakdown

| Level | Count |
|-------|-------|
| Safe | {summary.safe} |
| Caution | {summary.caution} |
| Danger | {summary.danger} |

"""

    if danger_events:
        md += "## Dangerous Actions\n\n"
        md += "| Time | Action | Target | Reason |\n"
        md += "|------|--------|--------|--------|\n"
        for e in danger_events:
            time_str = _format_time(e.timestamp)
            action = "COMMAND" if e.type.value == "command" else e.type.value.upper()
            md += f"| {time_str} | {action} | `{e.path}` | {e.reason or '-'} |\n"
        md += "\n"

    if caution_events:
        md += "## Caution Actions\n\n"
        md += "| Time | Action | Target | Reason |\n"
        md += "|------|--------|--------|--------|\n"
        for e in caution_events:
            time_str = _format_time(e.timestamp)
            action = "COMMAND" if e.type.value == "command" else e.type.value.upper()
            md += f"| {time_str} | {action} | `{e.path}` | {e.reason or '-'} |\n"
        md += "\n"

    # Commands Executed section
    command_events = [e for e in events if e.type.value == "command"]
    if command_events:
        md += "## Commands Executed\n\n"
        md += "| # | Time | Command | Risk | Reason |\n"
        md += "|---|------|---------|------|--------|\n"
        for i, e in enumerate(command_events):
            time_str = _format_time(e.timestamp)
            if e.risk.value == "danger":
                risk_str = "🚨 DANGER"
            elif e.risk.value == "caution":
                risk_str = "⚠️ Caution"
            else:
                risk_str = "✅ Safe"
            md += f"| {i + 1} | {time_str} | `{e.path}` | {risk_str} | {e.reason or '-'} |\n"
        md += "\n"

    md += "## Full Event Timeline\n\n"
    md += "| # | Time | Action | Target | Risk |\n"
    md += "|---|------|--------|--------|------|\n"
    for i, e in enumerate(events):
        time_str = _format_time(e.timestamp)
        action = "COMMAND" if e.type.value == "command" else e.type.value.upper()
        if e.risk.value == "danger":
            risk_str = "🚨 DANGER"
        elif e.risk.value == "caution":
            risk_str = "⚠️ Caution"
        else:
            risk_str = "✅ Safe"
        md += f"| {i + 1} | {time_str} | {action} | `{e.path}` | {risk_str} |\n"

    md += f"\n---\n*Report generated by Unworldly v{session.version}*\n"

    return md


def report(
    session_path: str,
    output: str | None = None,
    format: str = "terminal",
) -> None:
    """Generate a security report from a recorded session.

    Args:
        session_path: Path to the session file or session ID.
        output: Output file path (for markdown format).
        format: Output format -- "terminal" or "md"/"markdown".
    """
    session = load_session(session_path)

    green = "\033[32m"
    gray = "\033[90m"
    white_bold = "\033[1;37m"
    white = "\033[37m"
    cyan = "\033[36m"
    yellow = "\033[33m"
    yellow_bold = "\033[1;33m"
    red = "\033[31m"
    red_bold = "\033[1;31m"
    reset = "\033[0m"

    if format in ("md", "markdown"):
        markdown = _generate_markdown(session)
        output_path = output or f"unworldly-report-{session.id}.md"
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(markdown)
        print(banner())
        print(f"{green}  Report saved: {output_path}{reset}")
        print("")
        return

    # Terminal format
    print(banner())
    print(f"{white_bold}  Security Report{reset}")
    print("")

    summary = session.summary
    if summary.risk_score >= 7:
        score_color = red_bold
    elif summary.risk_score >= 4:
        score_color = yellow_bold
    else:
        score_color = "\033[1;32m"

    print(f"  Session:   {white}{session.id}{reset}")
    print(f"  Directory: {gray}{session.directory}{reset}")
    start_str = datetime.fromisoformat(session.start_time.replace("Z", "+00:00")).strftime("%c")
    print(f"  Recorded:  {gray}{start_str}{reset}")
    if session.agent:
        print(f"  Agent:     {cyan}{session.agent.name}{reset} {gray}({session.agent.detected_via}){reset}")
    print("")

    # Integrity verification
    integrity = verify_session(session)
    print(verify_display(integrity))
    print(f"  Risk Score: {score_color}{summary.risk_score}/10{reset}")
    print("")
    print(
        f"  {green}●{reset} Safe: {summary.safe}  "
        f"{yellow}●{reset} Caution: {summary.caution}  "
        f"{red}●{reset} Danger: {summary.danger}"
    )
    print("")

    danger_events = [e for e in session.events if e.risk.value == "danger"]
    caution_events = [e for e in session.events if e.risk.value == "caution"]

    if danger_events:
        print(f"{red_bold}  Dangerous Actions:{reset}")
        for e in danger_events:
            time_str = _format_time(e.timestamp)
            action = "$> CMD" if e.type.value == "command" else e.type.value.upper()
            print(f"{red}    {time_str}  {action}  {e.path}  — {e.reason}{reset}")
        print("")

    if caution_events:
        print(f"{yellow_bold}  Caution Actions:{reset}")
        for e in caution_events:
            time_str = _format_time(e.timestamp)
            action = "$> CMD" if e.type.value == "command" else e.type.value.upper()
            print(f"{yellow}    {time_str}  {action}  {e.path}  — {e.reason}{reset}")
        print("")

    if summary.risk_score >= 7:
        print(f"{red_bold}  ⚠ HIGH RISK SESSION — Review dangerous actions above{reset}")
    elif summary.risk_score >= 4:
        print(f"{yellow}  Some concerning activity detected — review caution items{reset}")
    else:
        print(f"{green}  Session looks clean — no major concerns{reset}")
    print("")

    # Suggest markdown export
    print(f"{gray}  Export full report: unworldly report {session_path} --format md{reset}")
    print("")
