import hashlib
import json
from datetime import datetime
from pathlib import Path
from unittest import TestCase

from api.services.integration.outbox import canonical_hash


FIXTURE_ROOT = (
    Path(__file__).resolve().parents[2]
    / "tests"
    / "contracts"
    / "resource_booking_phase1_v2"
)


class ResourceBookingContractFixtureTests(TestCase):
    def test_live_change_set_fixture_is_complete_ordered_and_hash_verified(self):
        fixture = FIXTURE_ROOT / "change_set.json"
        self.assertEqual(
            hashlib.sha256(fixture.read_bytes()).hexdigest(),
            "bf4ae32e685af60415f768fd567fab0423086d5c67ec41dc262142a51e2f2d92",
        )
        envelope = json.loads(fixture.read_text())
        events = envelope["events"]
        self.assertEqual(len(events), 3)
        self.assertEqual([event["transport"]["sequence"] for event in events], [101, 101, 101])
        self.assertEqual(
            [event["transport"]["transaction_index"] for event in events],
            [1, 2, 3],
        )
        self.assertEqual({event["transport"]["transaction_count"] for event in events}, {3})
        self.assertEqual({event["ordering_key"] for event in events}, {"tenant:default"})
        self.assertEqual({event["schema_version"] for event in events}, {"2"})
        self.assertEqual(
            {event["aggregate"]["aggregate_type"] for event in events},
            {"activity", "location", "staff"},
        )
        self.assertEqual(envelope["source_sequence"], 101)
        self.assertEqual(envelope["transaction_count"], 3)
        self.assertTrue(envelope["complete"])
        self.assertEqual(envelope["events_hash"], canonical_hash(events))
        for event in events:
            self.assertTrue(event["transport"]["member_only"])
            self.assertEqual(event["committed_state_hash"], canonical_hash(event["committed_state"]))
            self.assertIsNotNone(datetime.fromisoformat(event["committed_at"].replace("Z", "+00:00")).tzinfo)
        activity = events[-1]["committed_state"]["replacement"]["current"]
        occurrence = activity["occurrences"][0]
        self.assertEqual(occurrence["week_start_date"], "2026-05-18")
        self.assertEqual(occurrence["utc_start"], "2026-05-20T01:00:00Z")
        self.assertEqual(occurrence["local_start"], "2026-05-20T09:00:00+08:00")

    def test_snapshot_page_fixture_matches_bounded_http_wrapper(self):
        page = json.loads((FIXTURE_ROOT / "snapshot_page.json").read_text())
        self.assertEqual(
            set(page),
            {"schema_version", "snapshot_watermark", "next_cursor", "complete", "envelopes"},
        )
        self.assertEqual(page["schema_version"], "2")
        self.assertEqual(page["snapshot_watermark"], "0")
        self.assertTrue(page["complete"])
        self.assertIsNone(page["next_cursor"])
        self.assertEqual(page["envelopes"], [])
