from __future__ import annotations

import json
from collections import Counter
from dataclasses import asdict
from pathlib import Path
from typing import Any

from .test_runner import TestResult


class Reporter:
    def __init__(self, results: list[TestResult], run_meta: dict[str, Any], output_dir: str) -> None:
        self.results = results
        self.run_meta = run_meta
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(parents=True, exist_ok=True)

    def summary_counts(self) -> Counter:
        return Counter(r.status for r in self.results)

    def print_summary(self) -> None:
        c = self.summary_counts()
        total = len(self.results)
        print("\n== Didactyl Test Results ==")
        print(f"Run: {self.run_meta.get('run_timestamp', 'unknown')}")
        print(f"Agent base URL: {self.run_meta.get('base_url', 'unknown')}")
        print("")
        for k in ["pass", "fail", "error", "timeout", "skip"]:
            print(f"{k.capitalize():<8}: {c.get(k, 0)}")
        print(f"Total   : {total}")

    def print_details(self) -> None:
        bad = [r for r in self.results if r.status in {"fail", "error", "timeout"}]
        if not bad:
            return
        print("\n-- Non-passing tests --")
        for r in bad:
            print(f"[{r.status.upper()}] {r.suite}::{r.name}")
            print(f"  {r.message}")
            if r.agent_errors:
                print(f"  Agent errors: {len(r.agent_errors)}")

    def write_json(self, path: str = "results.json") -> Path:
        p = self.output_dir / path
        payload = {
            "run_meta": self.run_meta,
            "results": [asdict(r) for r in self.results],
            "summary": dict(self.summary_counts()),
        }
        p.write_text(json.dumps(payload, indent=2), encoding="utf-8")
        return p

    def write_text(self, path: str = "results.txt") -> Path:
        p = self.output_dir / path
        c = self.summary_counts()
        lines = [
            "== Didactyl Test Results ==",
            f"Run: {self.run_meta.get('run_timestamp', 'unknown')}",
            f"Agent base URL: {self.run_meta.get('base_url', 'unknown')}",
            "",
            f"Pass: {c.get('pass', 0)}",
            f"Fail: {c.get('fail', 0)}",
            f"Error: {c.get('error', 0)}",
            f"Timeout: {c.get('timeout', 0)}",
            f"Skip: {c.get('skip', 0)}",
            f"Total: {len(self.results)}",
            "",
        ]
        for r in self.results:
            lines.append(f"[{r.status.upper()}] {r.suite}::{r.name} ({r.duration_seconds:.2f}s)")
            lines.append(f"  {r.message}")
            if r.agent_errors:
                lines.append(f"  Agent errors: {len(r.agent_errors)}")
            lines.append("")
        p.write_text("\n".join(lines), encoding="utf-8")
        return p
