import sqlite3
from pathlib import Path
from unittest.mock import patch

import pytest


@pytest.fixture
def db_path(tmp_path):
    return tmp_path / "test.db"


@pytest.fixture
def make_orchestrator(db_path):
    def _make():
        with patch("onako.tmux_orchestrator.TmuxOrchestrator._ensure_session"), \
             patch("onako.tmux_orchestrator.TmuxOrchestrator.rediscover_tasks"):
            from onako.tmux_orchestrator import TmuxOrchestrator
            orch = TmuxOrchestrator(session_name="test", db_path=db_path)
            return orch
    return _make


def test_get_stats_empty(make_orchestrator):
    """Stats with no events should return zero volumes."""
    orch = make_orchestrator()
    stats = orch.get_stats()
    assert stats["volume"]["total_tasks"] == 0
    assert stats["volume"]["total_messages_sent"] == 0
    assert stats["volume"]["total_resumes"] == 0
    assert stats["volume"]["total_kills"] == 0
    assert stats["volume"]["total_interrupts"] == 0
    assert stats["volume"]["total_runtime_seconds"] == 0


def test_get_stats_volume_counts(make_orchestrator, db_path):
    """Stats should count events by type."""
    orch = make_orchestrator()
    conn = sqlite3.connect(db_path)
    events = [
        ("task_created", "t1", "2026-01-15T10:00:00+00:00"),
        ("task_created", "t2", "2026-01-15T11:00:00+00:00"),
        ("task_completed", "t1", "2026-01-15T12:00:00+00:00"),
        ("message_sent", "t2", "2026-01-15T11:05:00+00:00"),
        ("message_sent", "t2", "2026-01-15T11:10:00+00:00"),
        ("task_resumed", "t1", "2026-01-16T10:00:00+00:00"),
        ("task_killed", "t2", "2026-01-16T12:00:00+00:00"),
        ("task_interrupted", "t1", "2026-01-15T10:30:00+00:00"),
    ]
    for et, tid, ts in events:
        conn.execute(
            "INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
            (et, tid, ts),
        )
    conn.commit()
    conn.close()

    stats = orch.get_stats()
    assert stats["volume"]["total_tasks"] == 2
    assert stats["volume"]["total_messages_sent"] == 2
    assert stats["volume"]["total_resumes"] == 1
    assert stats["volume"]["total_kills"] == 1
    assert stats["volume"]["total_interrupts"] == 1


def test_get_stats_runtime(make_orchestrator, db_path):
    """Runtime should be computed from task_created to task_completed pairs."""
    orch = make_orchestrator()
    conn = sqlite3.connect(db_path)
    conn.execute(
        "INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
        ("task_created", "t1", "2026-01-15T10:00:00+00:00"),
    )
    conn.execute(
        "INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
        ("task_completed", "t1", "2026-01-15T12:00:00+00:00"),
    )
    conn.commit()
    conn.close()

    stats = orch.get_stats()
    assert stats["volume"]["total_runtime_seconds"] == 7200


def test_get_stats_records(make_orchestrator, db_path):
    """Records should find longest task and most resumed task."""
    orch = make_orchestrator()
    orch.tasks["t1"] = {"id": "t1", "prompt": "short task", "status": "done", "started_at": None, "origin": "managed", "last_activity": None, "claude_session_id": None, "branch": None, "worktree_path": None}
    orch.tasks["t2"] = {"id": "t2", "prompt": "long task", "status": "done", "started_at": None, "origin": "managed", "last_activity": None, "claude_session_id": None, "branch": None, "worktree_path": None}

    conn = sqlite3.connect(db_path)
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t1", "2026-01-15T10:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_completed", "t1", "2026-01-15T11:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t2", "2026-01-15T10:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_completed", "t2", "2026-01-15T13:00:00+00:00"))
    for i in range(3):
        conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                     ("task_resumed", "t1", f"2026-01-16T{10+i}:00:00+00:00"))
    conn.commit()
    conn.close()

    stats = orch.get_stats()
    assert stats["records"]["longest_task"]["id"] == "t2"
    assert stats["records"]["longest_task"]["duration_seconds"] == 10800
    assert stats["records"]["most_resumed_task"]["id"] == "t1"
    assert stats["records"]["most_resumed_task"]["resume_count"] == 3


def test_get_stats_heatmap(make_orchestrator, db_path):
    """Heatmap should count events per day."""
    orch = make_orchestrator()
    conn = sqlite3.connect(db_path)
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t1", "2026-01-15T10:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("message_sent", "t1", "2026-01-15T11:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t2", "2026-01-16T10:00:00+00:00"))
    conn.commit()
    conn.close()

    stats = orch.get_stats()
    assert stats["heatmap"].get("2026-01-15") == 2
    assert stats["heatmap"].get("2026-01-16") == 1


def test_get_stats_activity_by_hour(make_orchestrator, db_path):
    """Activity by hour should bucket events into 24 slots."""
    orch = make_orchestrator()
    conn = sqlite3.connect(db_path)
    for i in range(3):
        conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                     ("task_created", f"t{i}", f"2026-01-15T10:{i:02d}:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("message_sent", "t1", "2026-01-15T14:00:00+00:00"))
    conn.commit()
    conn.close()

    stats = orch.get_stats()
    assert len(stats["activity_by_hour"]) == 24
    assert stats["activity_by_hour"][10] == 3
    assert stats["activity_by_hour"][14] == 1
    assert stats["activity_by_hour"][0] == 0


def test_get_stats_trends(make_orchestrator, db_path):
    """Trends should group tasks and messages per ISO week."""
    orch = make_orchestrator()
    conn = sqlite3.connect(db_path)
    # Week 2026-W03 (Jan 12-18)
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t1", "2026-01-15T10:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t2", "2026-01-16T10:00:00+00:00"))
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("message_sent", "t1", "2026-01-15T11:00:00+00:00"))
    # Week 2026-W04 (Jan 19-25)
    conn.execute("INSERT INTO events (event_type, task_id, timestamp) VALUES (?, ?, ?)",
                 ("task_created", "t3", "2026-01-20T10:00:00+00:00"))
    conn.commit()
    conn.close()

    stats = orch.get_stats()
    tasks_per_week = {w["week"]: w["count"] for w in stats["trends"]["tasks_per_week"]}
    assert tasks_per_week.get("2026-W03") == 2
    assert tasks_per_week.get("2026-W04") == 1
