from __future__ import annotations

import json
import unittest
from decimal import Decimal

from channel_analytics.contracts import (
    AggregatedRoomFact,
    AnalyticsError,
    build_dashboard,
)


class ChannelAnalyticsContractsTests(unittest.TestCase):
    def test_dashboard_keeps_manifest_order_empty_channels_and_frozen_totals(self):
        payload = build_dashboard(
            "2026-07",
            "2026-07-28T15:54:00+08:00",
            "2026-07-26",
            "a" * 64,
            ("B", "A", "EMPTY"),
            (
                AggregatedRoomFact("A", "RM2", 2, Decimal("100"), 6, 1),
                AggregatedRoomFact("B", "RM3", 3, Decimal("90"), 4, 2),
                AggregatedRoomFact("B", "RM2", 1, Decimal("50"), 2, 1),
            ),
            min_arrival_date="2026-07-01",
        )

        self.assertEqual(payload["version"], "1.2")
        self.assertEqual(payload["min_arrival_date"], "2026-07-01")
        self.assertEqual(
            [channel["worksheet"] for channel in payload["channels"]],
            ["B", "A", "EMPTY"],
        )
        self.assertEqual(payload["overall"]["totals"], {
            "rooms_sold": 6,
            "total_price": 240,
            "room_nights": 12,
            "reservation_rows": 4,
            "room_type_count": 2,
            "channel_count": 3,
        })
        self.assertEqual(payload["channels"][0]["totals"]["total_price"], 140)
        self.assertEqual(payload["channels"][2]["room_types"], [])
        self.assertEqual(
            [room["room_type"] for room in payload["channels"][0]["room_types"]],
            ["RM3", "RM2"],
        )

    def test_dashboard_rejects_channels_outside_manifest_and_private_rows_are_absent(self):
        with self.assertRaises(AnalyticsError):
            build_dashboard(
                "2026-07",
                "2026-07-28T15:54:00+08:00",
                "2026-07-26",
                "a" * 64,
                ("A",),
                (AggregatedRoomFact("B", "RM2", 1, Decimal("10"), 1, 1),),
            )
        serialized = json.dumps(
            build_dashboard(
                "2026-07",
                "2026-07-28T15:54:00+08:00",
                "2026-07-26",
                "a" * 64,
                ("A",),
                (AggregatedRoomFact("A", "RM2", 1, Decimal("10"), 1, 1),),
            ),
            ensure_ascii=False,
        ).lower()
        for forbidden in ("full_name", "confirmation_no", "disp_room_no", "res_comment"):
            self.assertNotIn(forbidden, serialized)


if __name__ == "__main__":
    unittest.main()
