"""Tests for CLI filing subcommand — end-to-end regulatory filing generation."""

from __future__ import annotations

import json
from pathlib import Path

import pytest

from orxaq.experiences.cli import main

# ── Fixtures ──────────────────────────────────────────────────


@pytest.fixture(scope="module")
def filing_out(tmp_path_factory) -> tuple[Path, int]:
    """Run `orxaq filing generate` once and return (output_dir, rc)."""
    out = tmp_path_factory.mktemp("cli_filing")
    rc = main(
        [
            "filing",
            "generate",
            "--institution-id",
            "CLI001",
            "--period",
            "2026Q1",
            "--output",
            str(out),
            "--seed",
            "7",
            "--n-samples",
            "80",
            "--horizon",
            "4",
        ]
    )
    return out, rc


# ── Basic dispatch ────────────────────────────────────────────


class TestCLIFilingDispatch:
    def test_generate_returns_zero(self, filing_out: tuple) -> None:
        _, rc = filing_out
        assert rc == 0

    def test_filing_no_subcommand_shows_help(self) -> None:
        """No subcommand → argparse shows help and exits."""
        with pytest.raises(SystemExit) as exc:
            main(["filing"])
        assert exc.value.code == 0

    def test_generate_help_exits(self) -> None:
        """--help exits via SystemExit(0)."""
        with pytest.raises(SystemExit) as exc:
            main(["filing", "generate", "--help"])
        assert exc.value.code == 0


# ── Output file existence ─────────────────────────────────────


class TestCLIFilingOutputFiles:
    def test_cecl_disclosure_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "cecl_disclosure.json").exists()

    def test_ccar_export_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "ccar_export.json").exists()

    def test_schedule_h1_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "schedule_h1.csv").exists()

    def test_scenario_comparison_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "scenario_comparison.csv").exists()

    def test_html_report_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "regulatory_report.html").exists()

    def test_markdown_report_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "regulatory_report.md").exists()

    def test_audit_trail_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "audit_trail.json").exists()

    def test_manifest_exists(self, filing_out: tuple) -> None:
        out, _ = filing_out
        assert (out / "manifest.json").exists()


# ── JSON mode ─────────────────────────────────────────────────


class TestCLIFilingJSON:
    def test_json_mode_returns_dict(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        rc = main(
            [
                "--json",
                "filing",
                "generate",
                "--institution-id",
                "JTEST",
                "--period",
                "2025Q4",
                "--output",
                str(tmp_path),
                "--seed",
                "1",
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, dict)

    def test_json_mode_has_output_dir(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "--json",
                "filing",
                "generate",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        data = json.loads(capsys.readouterr().out)
        assert "output_dir" in data

    def test_json_mode_has_institution_id(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "--json",
                "filing",
                "generate",
                "--institution-id",
                "IDB",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        data = json.loads(capsys.readouterr().out)
        assert data["institution_id"] == "IDB"

    def test_json_mode_has_period(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "--json",
                "filing",
                "generate",
                "--period",
                "2025Q3",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        data = json.loads(capsys.readouterr().out)
        assert data["period"] == "2025Q3"

    def test_json_mode_has_duration(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "--json",
                "filing",
                "generate",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        data = json.loads(capsys.readouterr().out)
        assert "duration_seconds" in data
        assert data["duration_seconds"] >= 0

    def test_json_mode_has_files_list(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "--json",
                "filing",
                "generate",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        data = json.loads(capsys.readouterr().out)
        assert "files" in data
        assert len(data["files"]) == 8

    def test_json_mode_audit_entries_positive(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "--json",
                "filing",
                "generate",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        data = json.loads(capsys.readouterr().out)
        assert data["audit_entries_count"] > 0


# ── Human-readable output ─────────────────────────────────────


class TestCLIFilingHumanOutput:
    def test_human_output_mentions_output_dir(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "filing",
                "generate",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        out = capsys.readouterr().out
        assert "Filing generated" in out

    def test_human_output_mentions_institution(
        self,
        tmp_path: Path,
        capsys: pytest.CaptureFixture,
    ) -> None:
        main(
            [
                "filing",
                "generate",
                "--institution-id",
                "ALPHA",
                "--output",
                str(tmp_path),
                "--n-samples",
                "60",
                "--horizon",
                "3",
            ]
        )
        out = capsys.readouterr().out
        assert "ALPHA" in out
