"""Report generation and GitHub posting for remote test results."""

from __future__ import annotations

import json
import logging
import subprocess
from datetime import datetime, timezone
from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from tests.remote.suites.base import SuiteResult

logger = logging.getLogger(__name__)

RESULTS_DIR = Path(__file__).parent / "results"


def generate_markdown_report(results: list[SuiteResult]) -> str:
    """Generate a markdown report from one or more suite results.

    Returns a formatted markdown string suitable for GitHub issue comments.
    """
    lines: list[str] = []
    timestamp = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d %H:%M UTC")

    lines.append(f"## Remote Test Report -- {timestamp}")
    lines.append("")

    # Summary table
    lines.append("### Summary")
    lines.append("")
    lines.append("| Device | Suite | Passed | Failed | Errors | Skipped | Duration | Status |")
    lines.append("|--------|-------|--------|--------|--------|---------|----------|--------|")

    for r in results:
        status = "PASS" if r.success else "FAIL"
        status_emoji = "+" if r.success else "x"
        lines.append(
            f"| {r.device_name} | {r.suite_name} | {r.passed} | {r.failed} | "
            f"{r.errors} | {r.skipped} | {r.total_duration_s:.1f}s | "
            f"[{status_emoji}] {status} |"
        )

    lines.append("")

    # Detailed results per suite
    for r in results:
        lines.append(f"### {r.device_name} / {r.suite_name}")
        lines.append("")

        if not r.steps:
            lines.append("_No steps recorded._")
            lines.append("")
            continue

        lines.append("| Step | Status | Duration | Details |")
        lines.append("|------|--------|----------|---------|")

        for step in r.steps:
            status_marker = {
                "passed": "[+]",
                "failed": "[x]",
                "error": "[!]",
                "skipped": "[-]",
            }.get(step.status.value, "[ ]")

            detail = step.description
            if step.error_message:
                detail = f"{step.description} -- {step.error_message}"

            # Truncate long details for the table
            if len(detail) > 120:
                detail = detail[:117] + "..."

            lines.append(f"| {step.name} | {status_marker} {step.status.value} | {step.duration_s:.1f}s | {detail} |")

        lines.append("")

        # Show stdout/stderr for failed steps
        failed_steps = [s for s in r.steps if s.status.value in ("failed", "error")]
        if failed_steps:
            lines.append("<details>")
            lines.append("<summary>Failed step details</summary>")
            lines.append("")

            for step in failed_steps:
                lines.append(f"**{step.name}**")
                if step.error_message:
                    lines.append(f"Error: {step.error_message}")
                if step.stdout:
                    lines.append("```")
                    lines.append(step.stdout[:2000])
                    lines.append("```")
                if step.stderr:
                    lines.append("stderr:")
                    lines.append("```")
                    lines.append(step.stderr[:2000])
                    lines.append("```")
                lines.append("")

            lines.append("</details>")
            lines.append("")

    lines.append("---")
    lines.append("_Generated by `tests/remote/cli.py`_")

    return "\n".join(lines)


def save_json_report(results: list[SuiteResult], filename: str | None = None) -> Path:
    """Save results as a JSON file in the results directory.

    Returns the path to the saved file.
    """
    RESULTS_DIR.mkdir(parents=True, exist_ok=True)

    if filename is None:
        ts = datetime.now(tz=timezone.utc).strftime("%Y%m%d_%H%M%S")
        devices = "-".join(r.device_name for r in results)
        filename = f"{ts}_{devices}.json"

    filepath = RESULTS_DIR / filename

    data = []
    for r in results:
        data.append(
            {
                "suite_name": r.suite_name,
                "device_name": r.device_name,
                "success": r.success,
                "passed": r.passed,
                "failed": r.failed,
                "errors": r.errors,
                "skipped": r.skipped,
                "total_duration_s": r.total_duration_s,
                "started_at": r.started_at,
                "finished_at": r.finished_at,
                "steps": [
                    {
                        "name": s.name,
                        "description": s.description,
                        "status": s.status.value,
                        "stdout": s.stdout,
                        "stderr": s.stderr,
                        "duration_s": s.duration_s,
                        "error_message": s.error_message,
                    }
                    for s in r.steps
                ],
            }
        )

    filepath.write_text(json.dumps(data, indent=2))
    logger.info("JSON report saved to %s", filepath)
    return filepath


def post_to_github(issue_number: int, markdown: str) -> bool:
    """Post a markdown comment to a GitHub issue using the gh CLI.

    Returns True if the comment was posted successfully.
    """
    try:
        result = subprocess.run(
            ["gh", "issue", "comment", str(issue_number), "--body", markdown],
            capture_output=True,
            text=True,
            timeout=30,
            check=False,
        )
        if result.returncode == 0:
            logger.info("Posted report to GitHub issue #%d", issue_number)
            return True
        logger.error("Failed to post to GitHub: %s", result.stderr)
        return False
    except FileNotFoundError:
        logger.error("gh CLI not found. Install with: https://cli.github.com/")
        return False
    except subprocess.TimeoutExpired:
        logger.error("GitHub comment timed out")
        return False
