from __future__ import annotations

import unittest

from booking_ingestion.excel import BookingExcelError
from booking_ingestion.excel_review import (
    BookingDraftItem,
    BookingDraftPage,
    BookingDraftSummary,
    validate_draft_id,
    validate_review_item_id,
    validate_review_item_ids,
    validate_review_quantity,
    validate_review_room_type,
)


class BookingExcelReviewContractTests(unittest.TestCase):
    def test_review_inputs_are_strict_and_normalized(self) -> None:
        draft_id = "bookingdraft-" + "a" * 32
        self.assertEqual(validate_draft_id(draft_id), draft_id)
        self.assertEqual(validate_review_item_id(7), 7)
        self.assertEqual(validate_review_item_ids([7, 8]), (7, 8))
        self.assertEqual(validate_review_room_type("  U-TWN\nVIP  "), "U-TWN VIP")
        self.assertEqual(validate_review_quantity(2), 2)

        for invalid in ("draft-1", "", None):
            with self.subTest(draft_id=invalid), self.assertRaises(BookingExcelError):
                validate_draft_id(invalid)
        for invalid in (True, 0, -1, "2"):
            with self.subTest(item_id=invalid), self.assertRaises(BookingExcelError):
                validate_review_item_id(invalid)
        for invalid in (None, [], [1, 1], [True], list(range(1, 52))):
            with self.subTest(item_ids=invalid), self.assertRaises(BookingExcelError):
                validate_review_item_ids(invalid)
        for invalid in (True, 0, 10_000, 1.5, "2"):
            with self.subTest(quantity=invalid), self.assertRaises(BookingExcelError):
                validate_review_quantity(invalid)

    def test_page_contract_exposes_review_state_without_hotel_detail(self) -> None:
        draft_id = "bookingdraft-" + "b" * 32
        summary = BookingDraftSummary(
            draft_id=draft_id,
            filename="Booking.xlsx",
            status="reviewing",
            source_rows=1,
            worksheet_count=1,
            distinct_group_codes=1,
            extracted_items=1,
            confirmed_items=0,
            pending_items=1,
            deleted_items=0,
            confirmed_room_quantity=0,
            created_at=None,
            updated_at=None,
        )
        item = BookingDraftItem(
            item_id=3,
            draft_id=draft_id,
            worksheet="Booking",
            row_no=9,
            item_no=1,
            tour_code="TOUR-1",
            room_type_raw="拼จU-4ค24",
            room_type_code=None,
            quantity=2,
            review_status="pending",
            automatic=False,
            source_fragment="【拼จU-4ค24】 2",
            updated_at=None,
        )

        payload = BookingDraftPage(summary, (item,), 1, 50, 0).to_dict()

        self.assertEqual(payload["summary"]["pending_items"], 1)
        self.assertEqual(payload["items"][0]["tour_code"], "TOUR-1")
        self.assertIsNone(payload["items"][0]["room_type"])
        self.assertEqual(payload["items"][0]["quantity"], 2)
        self.assertNotIn("hotel_raw", payload["items"][0])


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