"""Tests for CLI analytics subcommand."""

from __future__ import annotations

import json
import sys
from unittest import mock

import pytest

from orxaq.experiences import cli as cli_mod


@pytest.fixture(autouse=True)
def _tmp_db(tmp_path, monkeypatch):
    """Create a temp DB and patch _get_db_path to use it."""
    db_file = tmp_path / "test.db"
    # Seed the DB
    from orxaq.fabric.persistence import SQLiteStore

    with SQLiteStore(str(db_file)) as store:
        store.save_dag_snapshot("v1", '{"nodes":1}', {"tag": "alpha"})
        store.save_dag_snapshot("v2", '{"nodes":3}', {"tag": "beta"})
        store.log_event("dag.create", "alice", "created dag")
        store.log_event("dag.update", "bob", "added nodes")
        store.log_event("ecl.compute", "alice", "ECL batch run")
        store.put("config.mode", "prod")
        store.put("model.ver", "3")

    monkeypatch.setattr(cli_mod, "_get_db_path", lambda _args: str(db_file))


class TestCLIAnalyticsSummary:
    def test_summary_text(self, capsys):
        with mock.patch.object(sys, "argv", ["orxaq", "analytics", "summary"]):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "Snapshots: 2" in out
        assert "Audit events: 3" in out

    def test_summary_json(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "--json", "analytics", "summary"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["snapshots"] == 2
        assert data["events"] == 3


class TestCLIAnalyticsQueryEvents:
    def test_query_events_all(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "query-events"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "dag.create" in out

    def test_query_events_by_actor(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "query-events", "--actor", "bob"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "bob" in out
        assert "alice" not in out

    def test_query_events_json(self, capsys):
        with mock.patch.object(
            sys,
            "argv",
            ["orxaq", "--json", "analytics", "query-events", "--type", "ecl.compute"],
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["count"] == 1


class TestCLIAnalyticsQuerySnapshots:
    def test_query_snapshots_all(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "query-snapshots"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "v1" in out
        assert "v2" in out

    def test_query_snapshots_by_name(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "query-snapshots", "--name", "v1"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "v1" in out


class TestCLIAnalyticsAggregate:
    def test_aggregate_by_type(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "aggregate"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "Total: 3" in out

    def test_aggregate_by_actor_json(self, capsys):
        with mock.patch.object(
            sys,
            "argv",
            ["orxaq", "--json", "analytics", "aggregate", "--group-by", "actor"],
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert data["count"] == 3
        assert "alice" in data["groups"]


class TestCLIAnalyticsTimeline:
    def test_timeline_by_day(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "timeline"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "#" in out  # bar chart

    def test_timeline_json(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "--json", "analytics", "timeline"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        data = json.loads(capsys.readouterr().out)
        assert "buckets" in data


class TestCLIAnalyticsSearch:
    def test_search_found(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "search", "ECL"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "ECL" in out

    def test_search_not_found(self, capsys):
        with mock.patch.object(
            sys, "argv", ["orxaq", "analytics", "search", "ZZZZZ"]
        ):
            rc = cli_mod.main()
        assert rc == 0
        out = capsys.readouterr().out
        assert "No matches" in out
