"""Tests for timmy.events — SensoryEvent model."""

import json
from datetime import UTC, datetime

from timmy.events import SensoryEvent


class TestSensoryEvent:
    def test_defaults(self):
        ev = SensoryEvent(source="gitea", event_type="push")
        assert ev.source == "gitea"
        assert ev.event_type == "push"
        assert ev.actor == ""
        assert ev.data == {}
        assert isinstance(ev.timestamp, datetime)

    def test_custom_fields(self):
        ts = datetime(2025, 1, 1, tzinfo=UTC)
        ev = SensoryEvent(
            source="bitcoin",
            event_type="new_block",
            timestamp=ts,
            data={"height": 900_000},
            actor="network",
        )
        assert ev.data["height"] == 900_000
        assert ev.actor == "network"
        assert ev.timestamp == ts

    def test_to_dict(self):
        ev = SensoryEvent(source="time", event_type="morning")
        d = ev.to_dict()
        assert d["source"] == "time"
        assert d["event_type"] == "morning"
        assert isinstance(d["timestamp"], str)

    def test_to_json(self):
        ev = SensoryEvent(source="terminal", event_type="command", data={"cmd": "ls"})
        raw = ev.to_json()
        parsed = json.loads(raw)
        assert parsed["source"] == "terminal"
        assert parsed["data"]["cmd"] == "ls"

    def test_from_dict_roundtrip(self):
        ev = SensoryEvent(
            source="gitea",
            event_type="issue_opened",
            data={"number": 42},
            actor="alice",
        )
        d = ev.to_dict()
        restored = SensoryEvent.from_dict(d)
        assert restored.source == ev.source
        assert restored.event_type == ev.event_type
        assert restored.data == ev.data
        assert restored.actor == ev.actor

    def test_json_serializable(self):
        """SensoryEvent must be JSON-serializable (acceptance criterion)."""
        ev = SensoryEvent(source="gitea", event_type="push", data={"ref": "main"})
        raw = ev.to_json()
        parsed = json.loads(raw)
        assert parsed["source"] == "gitea"
