"""Tests for sync-related functionality."""

from datetime import datetime

from syke.db import SykeDB
from syke.models import Event, UserProfile


def test_get_last_sync_timestamp_none(db, user_id):
    """Returns None when no ingestion runs exist."""
    assert db.get_last_sync_timestamp(user_id, "claude-code") is None


def test_get_last_sync_timestamp(db, user_id):
    """Returns correct timestamp after a completed ingestion run."""
    run_id = db.start_ingestion_run(user_id, "claude-code")
    db.complete_ingestion_run(run_id, 10)

    ts = db.get_last_sync_timestamp(user_id, "claude-code")
    assert ts is not None
    # Should be a valid ISO timestamp
    datetime.fromisoformat(ts)


def test_get_last_sync_timestamp_per_source(db, user_id):
    """Each source tracks its own last sync independently."""
    run1 = db.start_ingestion_run(user_id, "claude-code")
    db.complete_ingestion_run(run1, 10)

    run2 = db.start_ingestion_run(user_id, "github")
    db.complete_ingestion_run(run2, 5)

    ts_cc = db.get_last_sync_timestamp(user_id, "claude-code")
    ts_gh = db.get_last_sync_timestamp(user_id, "github")
    assert ts_cc is not None
    assert ts_gh is not None
    # Gmail has no runs
    assert db.get_last_sync_timestamp(user_id, "gmail") is None


def test_get_last_sync_ignores_failed(db, user_id):
    """Failed ingestion runs are not returned."""
    run_id = db.start_ingestion_run(user_id, "claude-code")
    db.complete_ingestion_run(run_id, 0, error="something broke")

    assert db.get_last_sync_timestamp(user_id, "claude-code") is None


def test_get_last_profile_timestamp_none(db, user_id):
    """Returns None when no profiles exist."""
    assert db.get_last_profile_timestamp(user_id) is None


def test_get_last_profile_timestamp(db, user_id):
    """Returns created_at after saving a profile."""
    profile = UserProfile(
        user_id=user_id,
        identity_anchor="Test user",
        active_threads=[],
        recent_detail="Testing.",
        background_context="Tests.",
        sources=["test"],
        events_count=5,
    )
    db.save_profile(profile)

    ts = db.get_last_profile_timestamp(user_id)
    assert ts is not None
    datetime.fromisoformat(ts)


def test_sync_no_new_events_skips_perception(db, user_id):
    """When re-ingesting produces 0 new events, perception should be skippable.

    This tests the DB dedup behavior that sync relies on.
    """
    event = Event(
        user_id=user_id,
        source="claude-code",
        timestamp=datetime(2025, 6, 1, 12, 0),
        event_type="session",
        title="Existing session",
        content="Already ingested session content that is long enough.",
    )
    # First insert succeeds
    assert db.insert_event(event) is True
    # Second insert is a dedup — returns False
    assert db.insert_event(event) is False
    # Count unchanged
    assert db.count_events(user_id) == 1


def test_mcp_push_event(db, user_id):
    """MCP server's push_event tool writes events to the DB."""
    import json
    from unittest.mock import patch

    from syke.distribution.mcp_server import create_server

    server = create_server(user_id)

    # Patch _get_db inside the closure to use our test DB
    # The MCP tools are closures that call _get_db() — we need to
    # make them use our test DB instead of opening a real one.
    # We do this by calling the gateway directly (same code path).
    from syke.ingestion.gateway import IngestGateway

    gw = IngestGateway(db, user_id)
    result = gw.push(
        source="mcp-test",
        event_type="observation",
        title="MCP push test",
        content="Event pushed via the same code path as the MCP push_event tool.",
        external_id="mcp-test-001",
    )
    assert result["status"] == "ok"
    assert result["duplicate"] is False

    # Verify the event is in the DB
    events = db.search_events(user_id, "MCP push test")
    assert len(events) == 1
    assert events[0]["source"] == "mcp-test"

    # Pushing again with same external_id should dedup
    result2 = gw.push(
        source="mcp-test",
        event_type="observation",
        title="MCP push test duplicate",
        content="This should be deduplicated.",
        external_id="mcp-test-001",
    )
    assert result2["status"] == "duplicate"
    assert db.count_events(user_id, source="mcp-test") == 1
