"""Contract tests for emergency location Pydantic models.

These tests validate that EmergencyLocation model correctly parses CSV cache data
exported via PowerShell.

Note: Graph API does NOT expose emergency location endpoints. Emergency locations
are exported from Teams Admin Center via PowerShell (Get-CsOnlineLisLocation) and
stored in CSV cache. These tests validate the CSV-to-model parsing contract.
"""

from __future__ import annotations

from typing import Any

import pytest

from teams_phone.models import EmergencyLocation


@pytest.mark.contract
def test_emergency_location_schema() -> None:
    """Validate EmergencyLocation model against expected CSV structure.

    Tests that the model can parse a complete CSV row with all fields populated.
    This validates the contract between the PowerShell export format and the
    Pydantic model.
    """
    # Sample data matching PowerShell Get-CsOnlineLisLocation export format
    csv_row: dict[str, Any] = {
        "locationId": "00000000-0000-0000-0000-000000000001",
        "civicAddressId": "00000000-0000-0000-0000-000000000002",
        "description": "Building A - Floor 1",
        "companyName": "Contoso Corporation",
        "address": "123 Main Street",
        "city": "Seattle",
        "stateOrProvince": "WA",
        "postalCode": "98101",
        "countryOrRegion": "US",
        "isDefault": True,
    }

    # Validate model can parse the CSV row
    location = EmergencyLocation.model_validate(csv_row)

    assert location.location_id == "00000000-0000-0000-0000-000000000001"
    assert location.civic_address_id == "00000000-0000-0000-0000-000000000002"
    assert location.description == "Building A - Floor 1"
    assert location.company_name == "Contoso Corporation"
    assert location.address == "123 Main Street"
    assert location.city == "Seattle"
    assert location.state_or_province == "WA"
    assert location.postal_code == "98101"
    assert location.country_or_region == "US"
    assert location.is_default is True


@pytest.mark.contract
def test_emergency_location_minimal_fields() -> None:
    """Validate EmergencyLocation model with minimal required fields.

    Tests that the model handles rows where optional fields are None/empty,
    which can occur in real CSV exports.
    """
    # Minimal CSV row with only required fields
    csv_row: dict[str, Any] = {
        "locationId": "00000000-0000-0000-0000-000000000001",
        "civicAddressId": "00000000-0000-0000-0000-000000000002",
        "description": "Main Office",
        "isDefault": False,
        # Optional fields omitted
    }

    location = EmergencyLocation.model_validate(csv_row)

    assert location.location_id == "00000000-0000-0000-0000-000000000001"
    assert location.civic_address_id == "00000000-0000-0000-0000-000000000002"
    assert location.description == "Main Office"
    assert location.is_default is False
    # Optional fields should be None
    assert location.company_name is None
    assert location.address is None
    assert location.city is None
    assert location.state_or_province is None
    assert location.postal_code is None
    assert location.country_or_region is None


@pytest.mark.contract
def test_emergency_location_string_boolean_conversion() -> None:
    """Validate EmergencyLocation model handles string boolean from CSV.

    CSV files store boolean values as strings ("True"/"False"). The LocationService
    converts these before passing to the model. This test validates the model
    accepts proper boolean values.
    """
    # Test with True
    csv_row_true: dict[str, Any] = {
        "locationId": "00000000-0000-0000-0000-000000000001",
        "civicAddressId": "00000000-0000-0000-0000-000000000002",
        "description": "Default Location",
        "isDefault": True,
    }
    location_true = EmergencyLocation.model_validate(csv_row_true)
    assert location_true.is_default is True

    # Test with False
    csv_row_false: dict[str, Any] = {
        "locationId": "00000000-0000-0000-0000-000000000003",
        "civicAddressId": "00000000-0000-0000-0000-000000000004",
        "description": "Secondary Location",
        "isDefault": False,
    }
    location_false = EmergencyLocation.model_validate(csv_row_false)
    assert location_false.is_default is False


@pytest.mark.contract
def test_emergency_location_field_aliases() -> None:
    """Validate EmergencyLocation model field aliases match CSV headers.

    The model uses camelCase aliases to match the expected CSV column names
    from PowerShell export. This test validates all aliases work correctly.
    """
    # Build a row using all CSV headers (camelCase as in PowerShell export)
    csv_row: dict[str, Any] = {
        "locationId": "id-1",
        "civicAddressId": "civic-1",
        "description": "Test",
        "companyName": "Test Corp",
        "address": "1 Test St",
        "city": "Test City",
        "stateOrProvince": "TS",
        "postalCode": "12345",
        "countryOrRegion": "US",
        "isDefault": True,
    }

    # Verify all headers are accepted by the model
    location = EmergencyLocation.model_validate(csv_row)

    # Verify data was parsed correctly through aliases
    assert location.location_id == "id-1"
    assert location.civic_address_id == "civic-1"
    assert location.description == "Test"
    assert location.company_name == "Test Corp"
    assert location.address == "1 Test St"
    assert location.city == "Test City"
    assert location.state_or_province == "TS"
    assert location.postal_code == "12345"
    assert location.country_or_region == "US"
    assert location.is_default is True


@pytest.mark.contract
def test_emergency_location_extra_fields_rejected() -> None:
    """Validate EmergencyLocation model rejects unexpected fields.

    With extra='forbid', the model should raise ValidationError for any
    fields not defined in the schema. This detects CSV format changes.
    """
    csv_row: dict[str, Any] = {
        "locationId": "00000000-0000-0000-0000-000000000001",
        "civicAddressId": "00000000-0000-0000-0000-000000000002",
        "description": "Test",
        "isDefault": True,
        "unexpectedField": "should fail",  # Not in schema
    }

    with pytest.raises(Exception) as exc_info:
        EmergencyLocation.model_validate(csv_row)

    # Should be a Pydantic ValidationError for extra field
    assert (
        "unexpectedField" in str(exc_info.value)
        or "extra" in str(exc_info.value).lower()
    )
