"""Tests for temporal.stores.InMemoryStore."""

from datetime import date, datetime, timedelta, timezone

from temporal import Message, PeriodType, SummaryRecord
from temporal.stores import InMemoryStore


class TestInMemoryStoreMessages:
    def _ts(self, minute: int) -> datetime:
        return datetime(2026, 3, 2, 10, minute, 0, tzinfo=timezone.utc)

    def test_store_and_query(self):
        store = InMemoryStore()
        msgs = [
            Message(role="user", content="Hello", timestamp=self._ts(0)),
            Message(role="assistant", content="Hi", timestamp=self._ts(1)),
        ]
        store.store_messages(msgs)
        result = store.query_messages()
        assert len(result) == 2
        assert result[0].content == "Hello"
        assert result[1].content == "Hi"

    def test_query_after_filter(self):
        store = InMemoryStore()
        store.store_messages([
            Message(role="user", content="early", timestamp=self._ts(0)),
            Message(role="user", content="late", timestamp=self._ts(10)),
        ])
        result = store.query_messages(after=self._ts(5))
        assert len(result) == 1
        assert result[0].content == "late"

    def test_query_before_filter(self):
        store = InMemoryStore()
        store.store_messages([
            Message(role="user", content="early", timestamp=self._ts(0)),
            Message(role="user", content="late", timestamp=self._ts(10)),
        ])
        result = store.query_messages(before=self._ts(5))
        assert len(result) == 1
        assert result[0].content == "early"

    def test_query_limit(self):
        store = InMemoryStore()
        for i in range(10):
            store.store_messages([Message(role="user", content=f"msg-{i}", timestamp=self._ts(i))])
        result = store.query_messages(limit=3)
        assert len(result) == 3

    def test_query_ordered_by_timestamp(self):
        store = InMemoryStore()
        store.store_messages([
            Message(role="user", content="second", timestamp=self._ts(5)),
            Message(role="user", content="first", timestamp=self._ts(1)),
            Message(role="user", content="third", timestamp=self._ts(10)),
        ])
        result = store.query_messages()
        assert [m.content for m in result] == ["first", "second", "third"]


class TestInMemoryStoreSummaries:
    def test_upsert_creates(self):
        store = InMemoryStore()
        was_created = store.upsert_summary(
            PeriodType.FIVE_MINUTE,
            key={"date": date(2026, 3, 2), "hour": 10, "minute": 5},
            summary="test summary",
            message_count=5,
        )
        assert was_created is True
        assert store.has_summaries(PeriodType.FIVE_MINUTE)

    def test_upsert_updates_existing(self):
        store = InMemoryStore()
        store.upsert_summary(
            PeriodType.FIVE_MINUTE,
            key={"date": date(2026, 3, 2), "hour": 10, "minute": 5},
            summary="original",
            message_count=5,
        )
        was_created = store.upsert_summary(
            PeriodType.FIVE_MINUTE,
            key={"date": date(2026, 3, 2), "hour": 10, "minute": 5},
            summary="updated",
            message_count=8,
        )
        assert was_created is False
        all_summaries = store.get_all_summaries(PeriodType.FIVE_MINUTE)
        assert len(all_summaries) == 1
        assert all_summaries[0].summary == "updated"
        assert all_summaries[0].message_count == 8

    def test_get_summary_keys(self):
        store = InMemoryStore()
        store.upsert_summary(
            PeriodType.HOURLY,
            key={"date": date(2026, 3, 2), "hour": 10},
            summary="h1", message_count=20,
        )
        store.upsert_summary(
            PeriodType.HOURLY,
            key={"date": date(2026, 3, 2), "hour": 11},
            summary="h2", message_count=15,
        )
        keys = store.get_summary_keys(PeriodType.HOURLY)
        assert keys == {(date(2026, 3, 2), 10), (date(2026, 3, 2), 11)}

    def test_has_summaries_false_when_empty(self):
        store = InMemoryStore()
        assert store.has_summaries(PeriodType.DAILY) is False

    def test_query_summaries_range(self):
        store = InMemoryStore()
        for hr in range(8, 13):
            store.upsert_summary(
                PeriodType.HOURLY,
                key={"date": date(2026, 3, 2), "hour": hr},
                summary=f"hour-{hr}", message_count=10,
            )
        result = store.query_summaries(
            PeriodType.HOURLY,
            start=datetime(2026, 3, 2, 9, 0, tzinfo=timezone.utc),
            end=datetime(2026, 3, 2, 11, 0, tzinfo=timezone.utc),
        )
        summaries = [s.summary for s in result]
        assert "hour-9" in summaries
        assert "hour-10" in summaries
        assert "hour-8" not in summaries
        assert "hour-11" not in summaries

    def test_get_summaries_before(self):
        store = InMemoryStore()
        store.upsert_summary(
            PeriodType.DAILY,
            key={"date": date(2026, 3, 1)},
            summary="d1", message_count=50,
        )
        store.upsert_summary(
            PeriodType.DAILY,
            key={"date": date(2026, 3, 2)},
            summary="d2", message_count=60,
        )
        store.upsert_summary(
            PeriodType.DAILY,
            key={"date": date(2026, 3, 3)},
            summary="d3", message_count=40,
        )
        result = store.get_summaries_before(PeriodType.DAILY, date(2026, 3, 2))
        summaries = [s.summary for s in result]
        assert summaries == ["d1"]

    def test_get_all_summaries_ordered(self):
        store = InMemoryStore()
        store.upsert_summary(PeriodType.MONTHLY, key={"year": 2026, "month": 2}, summary="feb", message_count=100)
        store.upsert_summary(PeriodType.MONTHLY, key={"year": 2025, "month": 12}, summary="dec", message_count=80)
        store.upsert_summary(PeriodType.MONTHLY, key={"year": 2026, "month": 1}, summary="jan", message_count=90)
        result = store.get_all_summaries(PeriodType.MONTHLY)
        assert [s.summary for s in result] == ["dec", "jan", "feb"]
