import pytest

from datatypes.epc.construction_age_band import EpcConstructionAgeBand
from datatypes.epc.floor import EpcFloorDescriptions

from backend.onboarders.mappings.parity.as_built_floor_classifiers import (
    unknown_floor_as_built,
    unknown_floor_retrofitted,
    map_solid_floor_as_built,
    map_suspended_floor_as_built,
)


@pytest.mark.parametrize(
    "age_band,expected",
    [
        # Before 1900 / 1900–1929 → suspended, no insulation
        (EpcConstructionAgeBand.before_1900, EpcFloorDescriptions.suspended_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1900_to_1929, EpcFloorDescriptions.suspended_no_insulation_assumed),

        # 1930–1995 → solid, no insulation
        (EpcConstructionAgeBand.from_1930_to_1949, EpcFloorDescriptions.solid_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1950_to_1966, EpcFloorDescriptions.solid_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1967_to_1975, EpcFloorDescriptions.solid_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1976_to_1982, EpcFloorDescriptions.solid_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1983_to_1990, EpcFloorDescriptions.solid_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1991_to_1995, EpcFloorDescriptions.solid_no_insulation_assumed),

        # 1996–2002 → solid, limited insulation
        (EpcConstructionAgeBand.from_1996_to_2002, EpcFloorDescriptions.solid_limited_insulation_assumed),

        # 2003+ → solid, insulated
        (EpcConstructionAgeBand.from_2003_to_2006, EpcFloorDescriptions.solid_insulated_assumed),
        (EpcConstructionAgeBand.from_2012_to_2022, EpcFloorDescriptions.solid_insulated_assumed),
        (EpcConstructionAgeBand.from_2023_onwards, EpcFloorDescriptions.solid_insulated_assumed),
    ],
)
def test_unknown_floor_as_built(age_band, expected):
    assert unknown_floor_as_built(age_band) == expected


@pytest.mark.parametrize(
    "age_band,expected",
    [
        # Pre-1930 → suspended, insulated
        (EpcConstructionAgeBand.before_1900, EpcFloorDescriptions.suspended_insulated),
        (EpcConstructionAgeBand.from_1900_to_1929, EpcFloorDescriptions.suspended_insulated),

        # 1930+ → solid, insulated
        (EpcConstructionAgeBand.from_1930_to_1949, EpcFloorDescriptions.solid_insulated),
        (EpcConstructionAgeBand.from_1950_to_1966, EpcFloorDescriptions.solid_insulated),
        (EpcConstructionAgeBand.from_1976_to_1982, EpcFloorDescriptions.solid_insulated),
        (EpcConstructionAgeBand.from_2023_onwards, EpcFloorDescriptions.solid_insulated),
    ],
)
def test_unknown_floor_retrofitted(age_band, expected):
    assert unknown_floor_retrofitted(age_band) == expected


@pytest.mark.parametrize(
    "age_band,expected",
    [
        # 1983–1995 → no insulation
        (EpcConstructionAgeBand.from_1983_to_1990, EpcFloorDescriptions.solid_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1991_to_1995, EpcFloorDescriptions.solid_no_insulation_assumed),

        # 1996–2002 → limited insulation
        (EpcConstructionAgeBand.from_1996_to_2002, EpcFloorDescriptions.solid_limited_insulation_assumed),

        # 2003+ → insulated
        (EpcConstructionAgeBand.from_2003_to_2006, EpcFloorDescriptions.solid_insulated_assumed),
        (EpcConstructionAgeBand.from_2012_to_2022, EpcFloorDescriptions.solid_insulated_assumed),
        (EpcConstructionAgeBand.from_2023_onwards, EpcFloorDescriptions.solid_insulated_assumed),
    ],
)
def test_solid_floor_as_built(age_band, expected):
    assert map_solid_floor_as_built(age_band) == expected


@pytest.mark.parametrize(
    "age_band,expected",
    [
        # 1983–1995 → no insulation
        (EpcConstructionAgeBand.from_1983_to_1990, EpcFloorDescriptions.suspended_no_insulation_assumed),
        (EpcConstructionAgeBand.from_1991_to_1995, EpcFloorDescriptions.suspended_no_insulation_assumed),

        # 1996–2002 → limited insulation
        (EpcConstructionAgeBand.from_1996_to_2002, EpcFloorDescriptions.suspended_limited_insulation_assumed),

        # 2003+ → insulated
        (EpcConstructionAgeBand.from_2003_to_2006, EpcFloorDescriptions.suspended_insulated_assumed),
        (EpcConstructionAgeBand.from_2012_to_2022, EpcFloorDescriptions.suspended_insulated_assumed),
        (EpcConstructionAgeBand.from_2023_onwards, EpcFloorDescriptions.suspended_insulated_assumed),
    ],
)
def test_suspended_floor_as_built(age_band, expected):
    assert map_suspended_floor_as_built(age_band) == expected
