"""CLI coverage tests — v2: targeting remaining uncovered paths."""

from __future__ import annotations

import json
from pathlib import Path

import pytest

from orxaq.experiences.cli import main

# ---------------------------------------------------------------------------
# Credit fairness text output (covers indirect_effects loop, line 189)
# ---------------------------------------------------------------------------


class TestCreditFairnessText:
    def test_fairness_text_output(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["credit", "fairness"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Fair Lending Analysis" in out
        assert "Total effect" in out
        assert "Indirect paths" in out


# ---------------------------------------------------------------------------
# Discover text mode (covers consensus + PC text paths, lines 689-707)
# ---------------------------------------------------------------------------


class TestDiscoverText:
    def test_discover_consensus_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["discover", "--consensus"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Consensus" in out or "Discovery" in out or "edge" in out.lower()

    def test_discover_pc_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["discover"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Discovery" in out or "PC" in out or "skeleton" in out.lower()


# ---------------------------------------------------------------------------
# Validate JSON + generate modes (covers lines 726, 742)
# ---------------------------------------------------------------------------


class TestValidateModes:
    def test_validate_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "validate"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "total_implications" in data
        assert "passed" in data

    def test_validate_generate(self, capsys: pytest.CaptureFixture, tmp_path: Path) -> None:
        out_file = str(tmp_path / "synthetic.json")
        rc = main(["validate", "--generate", "--output", out_file])
        assert rc == 0
        assert Path(out_file).exists()


# ---------------------------------------------------------------------------
# Fabric profile text path with column details (lines 867-876)
# ---------------------------------------------------------------------------


class TestFabricProfileDetail:
    def test_profile_text_columns_csv(self, capsys: pytest.CaptureFixture, tmp_path: Path) -> None:
        """Profile with CSV data shows column details in text mode."""
        csv_file = tmp_path / "data.csv"
        csv_file.write_text("name,age,income\nalice,30,50000\nbob,25,60000\ncarol,35,70000\n")
        rc = main(["fabric", "profile", "--data", str(csv_file)])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Data Profile" in out
        # CSV columns are detected as str by profiler.
        assert "type=str" in out or "unique=" in out

    def test_profile_json_columns(self, capsys: pytest.CaptureFixture, tmp_path: Path) -> None:
        csv_file = tmp_path / "data.csv"
        csv_file.write_text("name,age,income\nalice,30,50000\nbob,25,60000\ncarol,35,70000\n")
        rc = main(["--json", "fabric", "profile", "--data", str(csv_file)])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["row_count"] == 3
        assert data["column_count"] == 3
        assert len(data["columns"]) == 3


# ---------------------------------------------------------------------------
# Fabric quality with gates filter (line 883)
# ---------------------------------------------------------------------------


class TestFabricQualityGates:
    def test_quality_with_gates_filter(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "fabric", "quality", "--gates", "completeness"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "all_passed" in data


# ---------------------------------------------------------------------------
# Simulate text output with Monte Carlo variable stats (line 998)
# ---------------------------------------------------------------------------


class TestSimulateMCVariableStats:
    def test_monte_carlo_text_var_stats(self, capsys: pytest.CaptureFixture) -> None:
        """Monte Carlo text output should show variable statistics."""
        rc = main(["simulate", "--scenario", "adverse", "--monte-carlo", "5"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Monte Carlo" in out
        assert "Impact score" in out


# ---------------------------------------------------------------------------
# Export stdout modes (no --output): lines 1413-1418, 1434, 1451
# ---------------------------------------------------------------------------


class TestExportStdout:
    def test_export_ecl_json_stdout(self, capsys: pytest.CaptureFixture) -> None:
        """ECL export JSON to stdout (no --output)."""
        rc = main(["--json", "export", "ecl"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "records" in data

    def test_export_edges_stdout(self, capsys: pytest.CaptureFixture) -> None:
        """Edges export to stdout (no --output)."""
        rc = main(["export", "edges"])
        assert rc == 0
        out = capsys.readouterr().out
        assert len(out) > 0

    def test_export_nodes_stdout(self, capsys: pytest.CaptureFixture) -> None:
        """Nodes export to stdout (no --output)."""
        rc = main(["export", "nodes"])
        assert rc == 0
        out = capsys.readouterr().out
        assert len(out) > 0

    def test_export_dag_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "export", "dag"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, dict)


# ---------------------------------------------------------------------------
# Model versions with real data (lines 1264-1276)
# ---------------------------------------------------------------------------


class TestModelVersionsDetail:
    def test_model_versions_with_data(self, capsys: pytest.CaptureFixture, tmp_path: Path) -> None:
        """Save then list versions with JSON detail."""
        store_dir = str(tmp_path / "store")
        rc = main(["model", "save", "--name", "test-v2", "--store", store_dir])
        assert rc == 0
        capsys.readouterr()  # Consume save output.
        rc = main(
            [
                "--json",
                "model",
                "versions",
                "--name",
                "test-v2",
                "--store",
                store_dir,
            ]
        )
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["name"] == "test-v2"
        assert len(data["versions"]) >= 1
        v = data["versions"][0]
        assert "entities" in v
        assert "edges" in v
        assert "content_hash" in v

    def test_model_versions_text(self, capsys: pytest.CaptureFixture, tmp_path: Path) -> None:
        store_dir = str(tmp_path / "store")
        rc = main(["model", "save", "--name", "test-v2t", "--store", store_dir])
        assert rc == 0
        capsys.readouterr()  # Consume save output.
        rc = main(
            [
                "model",
                "versions",
                "--name",
                "test-v2t",
                "--store",
                store_dir,
            ]
        )
        assert rc == 0
        out = capsys.readouterr().out
        assert "test-v2t" in out


# ---------------------------------------------------------------------------
# Batch subcommand tests (lines 1454-1594)
# ---------------------------------------------------------------------------


class TestBatchCLI:
    def test_batch_run_ecl_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "batch", "run", "ecl"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "job_id" in data

    def test_batch_list_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "batch", "list"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, (dict, list))

    def test_batch_stats_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "batch", "stats"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, dict)

    def test_batch_clear_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "batch", "clear"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, dict)


# ---------------------------------------------------------------------------
# Metrics subcommand text output (lines 1518-1594)
# ---------------------------------------------------------------------------


class TestMetricsText:
    def test_metrics_snapshot_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["metrics", "snapshot"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Metrics Snapshot" in out

    def test_metrics_health_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["metrics", "health"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Health" in out

    def test_metrics_recent_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["metrics", "recent"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Recent" in out or "task" in out.lower() or "No recent" in out


# ---------------------------------------------------------------------------
# Learn subcommand coverage (lines 1600-1750)
# ---------------------------------------------------------------------------


class TestLearnCLI:
    def test_learn_summary_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["learn", "summary"])
        assert rc == 0

    def test_learn_summary_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "learn", "summary"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, dict)

    def test_learn_experiments_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["learn", "experiments"])
        assert rc == 0

    def test_learn_experiments_json(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["--json", "learn", "experiments"])
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert isinstance(data, (dict, list))

    def test_learn_best_text(self, capsys: pytest.CaptureFixture) -> None:
        rc = main(["learn", "best"])
        assert rc == 0
