"""发票模块单元测试

覆盖发票分类、CSV 列定义、常量校验。
"""

from src.doc.invoice import (
    INVOICE_LEVEL_COLUMNS,
    INVOICE_TYPE_GENERAL,
    INVOICE_TYPE_HOTEL,
    INVOICE_TYPE_TRAIN,
    INVOICE_TYPE_TRAVEL,
    PAYMENT_RECORD_COLUMNS,
    classify_invoice_batch,
    is_travel_invoice,
)


class TestInvoiceConstants:
    """发票常量校验"""

    def test_travel_types_contain_train(self) -> None:
        assert INVOICE_TYPE_TRAIN in INVOICE_TYPE_TRAVEL

    def test_travel_types_contain_hotel(self) -> None:
        assert INVOICE_TYPE_HOTEL in INVOICE_TYPE_TRAVEL

    def test_general_not_in_travel(self) -> None:
        assert INVOICE_TYPE_GENERAL not in INVOICE_TYPE_TRAVEL

    def test_invoice_columns_not_empty(self) -> None:
        assert len(INVOICE_LEVEL_COLUMNS) > 0

    def test_payment_columns_not_empty(self) -> None:
        assert len(PAYMENT_RECORD_COLUMNS) > 0


class TestIsTravelInvoice:
    """差旅发票判断"""

    def test_train_is_travel(self) -> None:
        assert is_travel_invoice(INVOICE_TYPE_TRAIN) is True

    def test_hotel_is_travel(self) -> None:
        assert is_travel_invoice(INVOICE_TYPE_HOTEL) is True

    def test_general_not_travel(self) -> None:
        assert is_travel_invoice(INVOICE_TYPE_GENERAL) is False

    def test_unknown_not_travel(self) -> None:
        assert is_travel_invoice("未知类型") is False


class TestClassifyInvoiceBatch:
    """发票分类"""

    def test_empty_list(self) -> None:
        result = classify_invoice_batch([])
        assert result == {"travel": [], "general": []}

    def test_all_travel(self) -> None:
        invoices = [
            {"发票类型": INVOICE_TYPE_TRAIN, "发票号码": "001"},
            {"发票类型": INVOICE_TYPE_HOTEL, "发票号码": "002"},
        ]
        result = classify_invoice_batch(invoices)
        assert len(result["travel"]) == 2
        assert len(result["general"]) == 0

    def test_all_general(self) -> None:
        invoices = [
            {"发票类型": INVOICE_TYPE_GENERAL, "发票号码": "001"},
        ]
        result = classify_invoice_batch(invoices)
        assert len(result["travel"]) == 0
        assert len(result["general"]) == 1

    def test_mixed(self) -> None:
        invoices = [
            {"发票类型": INVOICE_TYPE_TRAIN, "发票号码": "001"},
            {"发票类型": INVOICE_TYPE_GENERAL, "发票号码": "002"},
        ]
        result = classify_invoice_batch(invoices)
        assert len(result["travel"]) == 1
        assert len(result["general"]) == 1

    def test_missing_type_defaults_to_general(self) -> None:
        invoices = [{"发票号码": "001"}]
        result = classify_invoice_batch(invoices)
        assert len(result["general"]) == 1
