from backend.ecmk_fetcher.xml_processor import (
    SapPropertyDetails,
    flatten_sap_property,
    parse_rdsap,
)


SAMPLE_XML = """<RdSAP-Report xmlns="https://epbr.digital.communities.gov.uk/xsd/rdsap">
<Report-Header>
    <Property>
        <Address>
            <Address-Line-1>1</Address-Line-1>
            <Address-Line-2>Fake Avenue</Address-Line-2>
            <Post-Town>Random</Post-Town>
            <Postcode>AB24 5CD</Postcode>
        </Address>
    </Property>
</Report-Header>

<SAP-Data>
    <SAP-Property-Details>
        <Property-Type>0</Property-Type>

        <SAP-Building-Parts>

            <SAP-Building-Part>
                <Building-Part-Number>1</Building-Part-Number>
                <Identifier>Main Dwelling</Identifier>
                <Construction-Age-Band>C</Construction-Age-Band>
                <Floor-Heat-Loss>7</Floor-Heat-Loss>

                <Roof-Construction>4</Roof-Construction>
                <Roof-Insulation-Location>2</Roof-Insulation-Location>
                <Roof-Insulation-Thickness>100mm</Roof-Insulation-Thickness>

                <Wall-Construction>4</Wall-Construction>
                <Wall-Insulation-Type>4</Wall-Insulation-Type>

                <SAP-Floor-Dimensions>
                    <SAP-Floor-Dimension>
                        <Heat-Loss-Perimeter quantity="metres">25.31</Heat-Loss-Perimeter>
                        <Room-Height quantity="metres">2.46</Room-Height>
                        <Total-Floor-Area quantity="square metres">43.61</Total-Floor-Area>
                        <Floor>0</Floor>
                        <Party-Wall-Length>0</Party-Wall-Length>
                    </SAP-Floor-Dimension>

                    <SAP-Floor-Dimension>
                        <Heat-Loss-Perimeter quantity="metres">26.16</Heat-Loss-Perimeter>
                        <Room-Height quantity="metres">2.44</Room-Height>
                        <Total-Floor-Area quantity="square metres">42.33</Total-Floor-Area>
                        <Floor>1</Floor>
                        <Party-Wall-Length>0</Party-Wall-Length>
                    </SAP-Floor-Dimension>
                </SAP-Floor-Dimensions>

            </SAP-Building-Part>

            <SAP-Building-Part>
                <Building-Part-Number>2</Building-Part-Number>
                <Identifier>Extension</Identifier>
                <Construction-Age-Band>C</Construction-Age-Band>

                <Roof-Construction>8</Roof-Construction>
                <Roof-Insulation-Location>7</Roof-Insulation-Location>
                <Sloping-Ceiling-Insulation-Thickness>AB</Sloping-Ceiling-Insulation-Thickness>

                <Wall-Construction>3</Wall-Construction>
                <Wall-Insulation-Type>4</Wall-Insulation-Type>

                <SAP-Floor-Dimensions>
                    <SAP-Floor-Dimension>
                        <Heat-Loss-Perimeter quantity="metres">6.85</Heat-Loss-Perimeter>
                        <Room-Height quantity="metres">2.24</Room-Height>
                        <Total-Floor-Area quantity="square metres">4.46</Total-Floor-Area>
                        <Floor>0</Floor>
                        <Party-Wall-Length>0</Party-Wall-Length>
                    </SAP-Floor-Dimension>
                </SAP-Floor-Dimensions>

            </SAP-Building-Part>

        </SAP-Building-Parts>

    </SAP-Property-Details>
</SAP-Data>
</RdSAP-Report>
"""


NO_ROOF_XML = """<RdSAP-Report xmlns="https://epbr.digital.communities.gov.uk/xsd/rdsap">
<Report-Header>
    <Property>
        <Address>
            <Address-Line-1>5</Address-Line-1>
            <Post-Town>Somewhere</Post-Town>
            <Postcode>XY1 2AB</Postcode>
        </Address>
    </Property>
</Report-Header>
<SAP-Data>
    <SAP-Property-Details>
        <Property-Type>0</Property-Type>
        <SAP-Building-Parts>
            <SAP-Building-Part>
                <Identifier>Main Dwelling</Identifier>
                <SAP-Floor-Dimensions>
                    <SAP-Floor-Dimension>
                        <Heat-Loss-Perimeter quantity="metres">10.0</Heat-Loss-Perimeter>
                        <Room-Height quantity="metres">2.5</Room-Height>
                        <Total-Floor-Area quantity="square metres">50.0</Total-Floor-Area>
                        <Floor>0</Floor>
                        <Party-Wall-Length>3.0</Party-Wall-Length>
                    </SAP-Floor-Dimension>
                </SAP-Floor-Dimensions>
            </SAP-Building-Part>
        </SAP-Building-Parts>
    </SAP-Property-Details>
</SAP-Data>
</RdSAP-Report>
"""


def test_parse_rdsap_contract():
    # arrange + act
    result: SapPropertyDetails = parse_rdsap(SAMPLE_XML)

    # assert
    assert result == {
        "reference": "1AB245CD",
        "address": "1, Fake Avenue, Random, AB24 5CD",
        "property_type": "House",
        "building_parts": [
            {
                "identifier": "Main Dwelling",
                "floors": [
                    {
                        "area_m2": 43.61,
                        "height_m": 2.46,
                        "heat_loss_perimeter_m": 25.31,
                        "party_wall_length_m": 0.0,
                    },
                    {
                        "area_m2": 42.33,
                        "height_m": 2.44,
                        "heat_loss_perimeter_m": 26.16,
                        "party_wall_length_m": 0.0,
                    },
                ],
                "roof": {
                    "construction": 4,
                    "insulation_location": 2,
                    "insulation_thickness_mm": 100.0,
                },
            },
            {
                "identifier": "Extension",
                "floors": [
                    {
                        "area_m2": 4.46,
                        "height_m": 2.24,
                        "heat_loss_perimeter_m": 6.85,
                        "party_wall_length_m": 0.0,
                    }
                ],
                "roof": {
                    "construction": 8,
                    "insulation_location": 7,
                },
            },
        ],
    }


ND_THICKNESS_XML = """<RdSAP-Report xmlns="https://epbr.digital.communities.gov.uk/xsd/rdsap">
<Report-Header>
    <Property>
        <Address>
            <Address-Line-1>1</Address-Line-1>
            <Post-Town>Somewhere</Post-Town>
            <Postcode>AB1 2CD</Postcode>
        </Address>
    </Property>
</Report-Header>
<SAP-Data>
    <SAP-Property-Details>
        <Property-Type>0</Property-Type>
        <SAP-Building-Parts>
            <SAP-Building-Part>
                <Identifier>Main Dwelling</Identifier>
                <Roof-Construction>4</Roof-Construction>
                <Roof-Insulation-Location>2</Roof-Insulation-Location>
                <Roof-Insulation-Thickness>ND</Roof-Insulation-Thickness>
                <SAP-Floor-Dimensions>
                    <SAP-Floor-Dimension>
                        <Heat-Loss-Perimeter quantity="metres">10.0</Heat-Loss-Perimeter>
                        <Room-Height quantity="metres">2.5</Room-Height>
                        <Total-Floor-Area quantity="square metres">50.0</Total-Floor-Area>
                        <Floor>0</Floor>
                        <Party-Wall-Length>0</Party-Wall-Length>
                    </SAP-Floor-Dimension>
                </SAP-Floor-Dimensions>
            </SAP-Building-Part>
        </SAP-Building-Parts>
    </SAP-Property-Details>
</SAP-Data>
</RdSAP-Report>
"""

ND_INSULATION_LOCATION_XML = """<RdSAP-Report xmlns="https://epbr.digital.communities.gov.uk/xsd/rdsap">
<Report-Header>
    <Property>
        <Address>
            <Address-Line-1>1</Address-Line-1>
            <Post-Town>Somewhere</Post-Town>
            <Postcode>AB1 2CD</Postcode>
        </Address>
    </Property>
</Report-Header>
<SAP-Data>
    <SAP-Property-Details>
        <Property-Type>0</Property-Type>
        <SAP-Building-Parts>
            <SAP-Building-Part>
                <Identifier>Main Dwelling</Identifier>
                <Roof-Construction>4</Roof-Construction>
                <Roof-Insulation-Location>ND</Roof-Insulation-Location>
                <Roof-Insulation-Thickness>250</Roof-Insulation-Thickness>
                <SAP-Floor-Dimensions>
                    <SAP-Floor-Dimension>
                        <Heat-Loss-Perimeter quantity="metres">10.0</Heat-Loss-Perimeter>
                        <Room-Height quantity="metres">2.5</Room-Height>
                        <Total-Floor-Area quantity="square metres">50.0</Total-Floor-Area>
                        <Floor>0</Floor>
                        <Party-Wall-Length>0</Party-Wall-Length>
                    </SAP-Floor-Dimension>
                </SAP-Floor-Dimensions>
            </SAP-Building-Part>
        </SAP-Building-Parts>
    </SAP-Property-Details>
</SAP-Data>
</RdSAP-Report>
"""


def test_parse_rdsap_nd_thickness():
    # 'ND' (not determined) is a valid value in the wild for Roof-Insulation-Thickness
    # — it should be retained as-is rather than raising

    # arrange + act
    result: SapPropertyDetails = parse_rdsap(ND_THICKNESS_XML)

    # assert
    assert result["building_parts"][0]["roof"] == {
        "construction": 4,
        "insulation_location": 2,
        "insulation_thickness_mm": "ND",
    }


def test_parse_rdsap_nd_location():
    # 'ND' (not determined) is a valid value in the wild for Roof-Insulation-Location
    # — it should be retained as-is rather than raising

    # arrange + act
    result: SapPropertyDetails = parse_rdsap(ND_INSULATION_LOCATION_XML)

    # assert
    assert result["building_parts"][0]["roof"] == {
        "construction": 4,
        "insulation_location": "ND",
        "insulation_thickness_mm": 250,
    }


def test_flatten_full():
    # Two building parts; Main Dwelling has two floors + full roof,
    # Extension has one floor + partial roof (no thickness)

    # arrange
    details: SapPropertyDetails = parse_rdsap(SAMPLE_XML)

    # act
    result = flatten_sap_property(details)

    # assert
    assert result == {
        "reference": "1AB245CD",
        "address": "1, Fake Avenue, Random, AB24 5CD",
        "property_type": "House",
        "main_dwelling_floor_1_area_m2": 43.61,
        "main_dwelling_floor_1_height_m": 2.46,
        "main_dwelling_floor_1_heat_loss_perimeter_m": 25.31,
        "main_dwelling_floor_1_party_wall_length_m": 0.0,
        "main_dwelling_floor_2_area_m2": 42.33,
        "main_dwelling_floor_2_height_m": 2.44,
        "main_dwelling_floor_2_heat_loss_perimeter_m": 26.16,
        "main_dwelling_floor_2_party_wall_length_m": 0.0,
        "main_dwelling_roof_construction": 4,
        "main_dwelling_roof_insulation_location": 2,
        "main_dwelling_roof_insulation_thickness_mm": 100.0,
        "extension_floor_1_area_m2": 4.46,
        "extension_floor_1_height_m": 2.24,
        "extension_floor_1_heat_loss_perimeter_m": 6.85,
        "extension_floor_1_party_wall_length_m": 0.0,
        "extension_roof_construction": 8,
        "extension_roof_insulation_location": 7,
    }


def test_flatten_no_roof():
    # Single building part with no roof — roof keys must be absent entirely

    # arrange
    details: SapPropertyDetails = parse_rdsap(NO_ROOF_XML)

    # act
    result = flatten_sap_property(details)

    # assert
    assert result == {
        "reference": "5XY12AB",
        "address": "5, Somewhere, XY1 2AB",
        "property_type": "House",
        "main_dwelling_floor_1_area_m2": 50.0,
        "main_dwelling_floor_1_height_m": 2.5,
        "main_dwelling_floor_1_heat_loss_perimeter_m": 10.0,
        "main_dwelling_floor_1_party_wall_length_m": 3.0,
    }
