import pytest
import pickle
import numpy as np
from recommendations.WindowsRecommendations import WindowsRecommendations
from backend.Property import Property
from recommendations.tests.test_data.materials import materials
from etl.epc.Record import EPCRecord


class TestWindowRecommendations:

    @pytest.fixture()
    def cleaning_data(self):
        with open("recommendations/tests/test_data/cleaning_data.pkl", "rb") as f:
            data = pickle.load(f)

        return data

    @pytest.fixture()
    def cleaned(self):
        with open("recommendations/tests/test_data/cleaned.pkl", "rb") as f:
            df = pickle.load(f)

        return df

    def test_fully_single_glazed(self):
        """
        For this property, we expect all windows to be single glazed and should recommend full double glazing
        :return:
        """
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 0
        epc_record.uprn = 0
        epc_record.windows_energy_eff = "Very Poor"
        epc_record.floor_area = 2.5
        epc_record.number_habitable_rooms = 5
        epc_record.number_heated_rooms = 5

        property_1 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_1.windows = {
            'original_description': 'Single glazed', 'clean_description': 'Single glazed',
            'has_glazing': False, 'glazing_coverage': 'full',
            'glazing_type': 'single',
            'no_data': False
        }
        property_1.number_of_windows = 7
        property_1.already_installed = []

        recommender = WindowsRecommendations(property_instance=property_1, materials=materials)

        assert not recommender.recommendation

        recommender.recommend()

        # The home is going from single glazing (v poor energy eff) -> double glazing (average energy eff)

        assert len(recommender.recommendation) == 1
        assert recommender.recommendation[0]["total"] == np.float64(7980.0)
        assert recommender.recommendation[0]["phase"] == 0
        assert recommender.recommendation[0]["description"] == 'Install double glazing to all windows'
        assert recommender.recommendation[0]["contingency"] == np.float64(1197.0)
        assert recommender.recommendation[0]["simulation_config"] == {
            'has_glazing_ending': True, 'glazing_type_ending': 'double',
            'multi_glaze_proportion_ending': 100, 'windows_energy_eff_ending': 'Good',
            'glazed_type_ending': 'double glazing installed during or after 2002'
        }

    def test_partial_double_glazed(self):
        """
        For this property, the double glazing is describes as partial, therefore we recommend completion of
        double glazing
        :return:
        """
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 33
        epc_record.uprn = 0
        epc_record.windows_energy_eff = "Good"  # This has been observed in the EPC data

        property_2 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_2.windows = {
            'original_description': 'Mostly double glazing',
            'clean_description': 'Mostly double glazing',
            'has_glazing': True,
            'glazing_coverage': 'most',
            'glazing_type': 'double', 'no_data': False
        }
        property_2.number_of_windows = 7
        property_2.already_installed = []

        recommender2 = WindowsRecommendations(property_instance=property_2, materials=materials)

        assert not recommender2.recommendation

        recommender2.recommend()

        assert len(recommender2.recommendation) == 1
        assert recommender2.recommendation[0]["total"] == np.float64(5700.0)
        assert recommender2.recommendation[0]["phase"] == 0
        assert recommender2.recommendation[0]["description"] == 'Install double glazing to all windows'
        assert recommender2.recommendation[0]["contingency"] == np.float64(855.0)
        assert recommender2.recommendation[0]["simulation_config"] == {
            'glazing_coverage_ending': 'full', 'multi_glaze_proportion_ending': 100,
            'windows_energy_eff_ending': 'Good', 'glazing_type_ending': 'double',
            'glazed_type_ending': 'double glazing installed during or after 2002'
        }

    def test_fully_double_glazed(self):
        """
        This property has full double glazing so we shouldn't recommend anything
        :return:
        """
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 100
        epc_record.uprn = 0

        property_3 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_3.windows = {
            'original_description': 'Fully double glazed', 'clean_description': 'Fully double glazed',
            'has_glazing': True,
            'glazing_coverage': 'full',
            'glazing_type': 'double', 'no_data': False
        }
        property_3.number_of_windows = 7
        property_3.already_installed = []

        recommender3 = WindowsRecommendations(property_instance=property_3, materials=materials)

        assert not recommender3.recommendation

        recommender3.recommend()

        assert not recommender3.recommendation

    def test_fully_secondary_glazed(self):
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 100
        epc_record.uprn = 0

        property_4 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_4.windows = {
            'original_description': 'Full secondary glazing',
            'clean_description': 'Full secondary glazing',
            'has_glazing': True,
            'glazing_coverage': 'full',
            'glazing_type': 'secondary', 'no_data': False
        }
        property_4.number_of_windows = 7
        property_4.already_installed = []

        recommender4 = WindowsRecommendations(property_instance=property_4, materials=materials)

        assert not recommender4.recommendation

        recommender4.recommend()

        assert not recommender4.recommendation

    def test_partial_secondary_glazing(self):
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 50
        epc_record.uprn = 0
        epc_record.windows_energy_eff = "Poor"  # This has been observed in the EPC data

        property_5 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_5.windows = {
            'original_description': 'Partial secondary glazing',
            'clean_description': 'Partial secondary glazing',
            'has_glazing': True,
            'glazing_coverage': 'partial',
            'glazing_type': 'secondary', 'no_data': False
        }
        property_5.number_of_windows = 7
        property_5.already_installed = []

        recommender5 = WindowsRecommendations(property_instance=property_5, materials=materials)

        assert not recommender5.recommendation

        recommender5.recommend()

        assert len(recommender5.recommendation) == 1
        assert recommender5.recommendation[0]["total"] == np.float64(4560.0)
        assert recommender5.recommendation[0]["phase"] == 0
        assert recommender5.recommendation[0]["description"] == 'Install double glazing to all windows'
        assert recommender5.recommendation[0]["contingency"] == np.float64(684.0)
        assert recommender5.recommendation[0]["simulation_config"] == {
            'glazing_coverage_ending': 'full', 'glazing_type_ending': 'multiple', 'multi_glaze_proportion_ending': 100,
            'windows_energy_eff_ending': 'Average', 'glazed_type_ending': 'secondary glazing'
        }

    def test_single_glazed_restricted_measures(self):
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 0
        epc_record.uprn = 0
        epc_record.windows_energy_eff = "Very Poor"

        property_6 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_6.windows = {
            'original_description': 'Single glazed', 'clean_description': 'Single glazed',
            'has_glazing': False, 'glazing_coverage': None,
            'glazing_type': 'single',
            'no_data': False
        }
        property_6.number_of_windows = 7
        property_6.restricted_measures = True
        property_6.is_heritage = True
        property_6.already_installed = []

        recommender6 = WindowsRecommendations(property_instance=property_6, materials=materials)

        assert not recommender6.recommendation

        recommender6.recommend()

        assert len(recommender6.recommendation) == 1
        assert recommender6.recommendation[0]["total"] == np.float64(7980.0)
        assert recommender6.recommendation[0]["phase"] == 0
        assert recommender6.recommendation[0]["contingency"] == np.float64(1197.0)
        assert recommender6.recommendation[0]["description"] == (
            'Install secondary glazing to all windows. Secondary glazing recommended due to herigate building status'
        )
        assert recommender6.recommendation[0]["simulation_config"] == {
            'has_glazing_ending': True, 'glazing_coverage_ending': 'full', 'glazing_type_ending': 'secondary',
            'multi_glaze_proportion_ending': 100, 'windows_energy_eff_ending': 'Good',
            'glazed_type_ending': 'secondary glazing'
        }

    def test_full_triple_glazed(self):
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 100
        epc_record.uprn = 0

        property_7 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_7.windows = {
            'original_description': 'Fully triple glazed', 'clean_description': 'Fully triple glazed',
            'has_glazing': True,
            'glazing_coverage': 'full',
            'glazing_type': 'triple', 'no_data': False
        }
        property_7.number_of_windows = 7
        property_7.already_installed = []

        recommender7 = WindowsRecommendations(property_instance=property_7, materials=materials)

        assert not recommender7.recommendation

        recommender7.recommend()

        assert not recommender7.recommendation

    def test_partial_triple_glazed(self):
        """
        We don't recommend anything here
        """
        epc_record = EPCRecord()
        epc_record.county = "Wychavon"
        epc_record.multi_glaze_proportion = 80
        epc_record.uprn = 1

        property_8 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_8.windows = {
            'original_description': 'Mostly triple glazing',
            'clean_description': 'Mostly triple glazing',
            'has_glazing': True,
            'glazing_coverage': 'most',
            'glazing_type': 'triple', 'no_data': False
        }
        property_8.number_of_windows = 7
        property_8.already_installed = []

        recommender8 = WindowsRecommendations(property_instance=property_8, materials=materials)

        assert not recommender8.recommendation

        recommender8.recommend()

        assert not recommender8.recommendation

    def test_simulating_outcome_single_glazed(self, cleaning_data, cleaned):

        epc = {
            'lmk-key': 'f4cf43c90ab3140112a9d1c8cfb21ec1bf73f5a2ca3c75118f289d3447dddf15', 'address1': '3 The Green',
            'address2': 'Old Dalby', 'address3': None, 'postcode': 'LE14 3LL',
            'building-reference-number': 10006291833, 'current-energy-rating': 'E', 'potential-energy-rating': 'B',
            'current-energy-efficiency': 47, 'potential-energy-efficiency': 82, 'property-type': 'House',
            'built-form': 'Semi-Detached', 'inspection-date': '2024-07-19', 'local-authority': 'E07000133',
            'constituency': 'E14000909', 'county': 'Leicestershire', 'lodgement-date': '2024-07-21',
            'transaction-type': 'rental', 'environment-impact-current': 41, 'environment-impact-potential': 79,
            'energy-consumption-current': 478, 'energy-consumption-potential': 155.0, 'co2-emissions-current': 5.1,
            'co2-emiss-curr-per-floor-area': 85, 'co2-emissions-potential': 1.7, 'lighting-cost-current': 91.0,
            'lighting-cost-potential': 91.0, 'heating-cost-current': 1677.0, 'heating-cost-potential': 874.0,
            'hot-water-cost-current': 161.0, 'hot-water-cost-potential': 109.0, 'total-floor-area': 61.0,
            'energy-tariff': 'dual', 'mains-gas-flag': 'Y', 'floor-level': None, 'flat-top-storey': None,
            'flat-storey-count': None, 'main-heating-controls': None, 'multi-glaze-proportion': 0.0,
            'glazed-type': 'not defined', 'glazed-area': 'Normal', 'extension-count': 3.0,
            'number-habitable-rooms': 4.0, 'number-heated-rooms': 4.0, 'low-energy-lighting': 100.0,
            'number-open-fireplaces': 0.0, 'hotwater-description': 'From main system',
            'hot-water-energy-eff': 'Good', 'hot-water-env-eff': 'Good',
            'floor-description': 'Solid, no insulation (assumed)', 'floor-energy-eff': None, 'floor-env-eff': None,
            'windows-description': 'Single glazed', 'windows-energy-eff': 'Very Poor',
            'windows-env-eff': 'Very Poor', 'walls-description': 'Solid brick, as built, no insulation (assumed)',
            'walls-energy-eff': 'Very Poor', 'walls-env-eff': 'Very Poor', 'secondheat-description': 'None',
            'sheating-energy-eff': None, 'sheating-env-eff': None,
            'roof-description': 'Pitched, no insulation (assumed)', 'roof-energy-eff': 'Very Poor',
            'roof-env-eff': 'Very Poor', 'mainheat-description': 'Boiler and radiators, mains gas',
            'mainheat-energy-eff': 'Good', 'mainheat-env-eff': 'Good',
            'mainheatcont-description': 'Programmer and room thermostat', 'mainheatc-energy-eff': 'Average',
            'mainheatc-env-eff': 'Average', 'lighting-description': 'Low energy lighting in all fixed outlets',
            'lighting-energy-eff': 'Very Good', 'lighting-env-eff': 'Very Good',
            'main-fuel': 'mains gas (not community)', 'wind-turbine-count': 0.0, 'heat-loss-corridor': None,
            'unheated-corridor-length': None, 'floor-height': 2.37, 'photo-supply': 0.0,
            'solar-water-heating-flag': 'N', 'mechanical-ventilation': 'natural',
            'address': '3 The Green, Old Dalby', 'local-authority-label': 'Melton',
            'constituency-label': 'Rutland and Melton', 'posttown': 'MELTON MOWBRAY',
            'construction-age-band': 'England and Wales: before 1900', 'lodgement-datetime': '2024-07-21 19:29:04',
            'tenure': 'Rented (private)', 'fixed-lighting-outlets-count': 7.0, 'low-energy-fixed-light-count': None,
            'uprn': 200001041444.0, 'uprn-source': 'Energy Assessor'
        }

        epc_records = {
            "original_epc": epc,
            "full_sap_epc": {},
            "old_data": []
        }

        epc_record = EPCRecord(
            epc_records=epc_records,
            run_mode="newdata",
            cleaning_data=cleaning_data
        )

        property_9 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_9.windows = {
            'original_description': 'Single glazed',
            'clean_description': 'Single glazed',
            'has_glazing': False, 'glazing_coverage': None,
            'glazing_type': 'single',
            'no_data': False
        }
        property_9.perimeter = 23.430749027719962

        property_9.number_of_windows = 7
        property_9.restricted_measures = False
        property_9.is_heritage = False
        property_9.already_installed = []

        recommender9 = WindowsRecommendations(property_instance=property_9, materials=materials)

        assert not recommender9.recommendation

        recommender9.recommend()

        assert recommender9.recommendation[0]["total"] == np.float64(7980.0)
        assert recommender9.recommendation[0]["phase"] == 0
        assert recommender9.recommendation[0]["description"] == 'Install double glazing to all windows'
        assert recommender9.recommendation[0]["contingency"] == np.float64(1197.0)

        # We now simulate the outcome
        windows_rec = recommender9.recommendation.copy()
        windows_rec[0]["recommendation_id"] = 1
        property_recommendations = [windows_rec]

        property_9.create_base_difference_epc_record(cleaned_lookup=cleaned)

        starting_record = property_9.base_difference_record.df.to_dict("records")[0]

        expected_base_difference_record = {
            'uprn': 200001041444, 'rdsap_change': 0, 'heat_demand_change': 0, 'carbon_change': 0.0,
            'potential_energy_efficiency': 82.0, 'environment_impact_potential': 79.0,
            'energy_consumption_potential': 155.0, 'co2_emissions_potential': 1.7, 'property_type': 'House',
            'built_form': 'Semi-Detached', 'constituency': 'E14000909', 'number_habitable_rooms': 4.0,
            'number_heated_rooms': 4.0, 'construction_age_band': 'England and Wales: before 1900',
            'fixed_lighting_outlets_count': 7.0, 'walls_thermal_transmittance': 1.7,
            'walls_thermal_transmittance_unit': 'Unknown', 'is_cavity_wall': False, 'is_filled_cavity': False,
            'is_solid_brick': True, 'is_system_built': False, 'is_timber_frame': False,
            'is_granite_or_whinstone': False, 'is_as_built': True, 'is_cob': False, 'walls_is_assumed': True,
            'is_sandstone_or_limestone': False, 'is_park_home': False, 'walls_insulation_thickness': 'none',
            'external_insulation': False, 'internal_insulation': False, 'floor_thermal_transmittance': 0.96,
            'is_to_unheated_space': False, 'is_to_external_air': False, 'is_suspended': False, 'is_solid': True,
            'another_property_below': False, 'floor_insulation_thickness': 'none', 'roof_thermal_transmittance': 2.3,
            'is_pitched': True, 'is_roof_room': False, 'is_loft': False, 'is_flat': False, 'is_thatched': False,
            'is_at_rafters': False, 'has_dwelling_above': False, 'roof_insulation_thickness': 'none',
            'heater_type': 'Unknown', 'system_type': 'from main system', 'thermostat_characteristics': 'Unknown',
            'heating_scope': 'Unknown', 'energy_recovery': 'Unknown', 'hotwater_tariff_type': 'Unknown',
            'extra_features': 'Unknown', 'chp_systems': 'Unknown', 'distribution_system': 'Unknown',
            'no_system_present': 'Unknown', 'appliance': 'Unknown', 'has_radiators': True, 'has_fan_coil_units': False,
            'has_pipes_in_screed_above_insulation': False, 'has_pipes_in_insulated_timber_floor': False,
            'has_pipes_in_concrete_slab': False, 'has_boiler': True, 'has_air_source_heat_pump': False,
            'has_room_heaters': False, 'has_electric_storage_heaters': False, 'has_warm_air': False,
            'has_electric_underfloor_heating': False, 'has_electric_ceiling_heating': False,
            'has_community_scheme': False, 'has_ground_source_heat_pump': False, 'has_no_system_present': False,
            'has_portable_electric_heaters': False, 'has_water_source_heat_pump': False,
            'has_electric_heat_pump': False, 'has_micro-cogeneration': False, 'has_solar_assisted_heat_pump': False,
            'has_exhaust_source_heat_pump': False, 'has_community_heat_pump': False, 'has_electric': False,
            'has_mains_gas': True, 'has_wood_logs': False, 'has_coal': False, 'has_oil': False,
            'has_wood_pellets': False, 'has_anthracite': False, 'has_dual_fuel_mineral_and_wood': False,
            'has_smokeless_fuel': False, 'has_lpg': False, 'has_b30k': False, 'has_electricaire': False,
            'has_assumed_for_most_rooms': False, 'has_underfloor_heating': False,
            'thermostatic_control': 'room thermostat', 'charging_system': 'Unknown', 'switch_system': 'programmer',
            'no_control': 'Unknown', 'dhw_control': 'Unknown', 'community_heating': 'Unknown',
            'multiple_room_thermostats': False, 'auxiliary_systems': 'Unknown', 'trvs': 'Unknown',
            'rate_control': 'Unknown', 'glazing_type': 'single', 'fuel_type': 'mains gas',
            'main-fuel_tariff_type': 'Unknown', 'is_community': False,
            'no_individual_heating_or_community_network': False, 'complex_fuel_type': 'Unknown',
            'walls_thermal_transmittance_ending': 1.7, 'walls_thermal_transmittance_unit_ending': 'Unknown',
            'is_filled_cavity_ending': False, 'is_as_built_ending': True, 'walls_is_assumed_ending': True,
            'is_park_home_ending': False, 'walls_insulation_thickness_ending': 'none',
            'external_insulation_ending': False, 'internal_insulation_ending': False,
            'floor_thermal_transmittance_ending': 0.96, 'floor_insulation_thickness_ending': 'none',
            'roof_thermal_transmittance_ending': 2.3, 'is_at_rafters_ending': False,
            'roof_insulation_thickness_ending': 'none', 'heater_type_ending': 'Unknown',
            'system_type_ending': 'from main system', 'thermostat_characteristics_ending': 'Unknown',
            'heating_scope_ending': 'Unknown', 'energy_recovery_ending': 'Unknown',
            'hotwater_tariff_type_ending': 'Unknown', 'extra_features_ending': 'Unknown',
            'chp_systems_ending': 'Unknown', 'distribution_system_ending': 'Unknown',
            'no_system_present_ending': 'Unknown', 'appliance_ending': 'Unknown', 'has_radiators_ending': True,
            'has_fan_coil_units_ending': False, 'has_pipes_in_screed_above_insulation_ending': False,
            'has_pipes_in_insulated_timber_floor_ending': False, 'has_pipes_in_concrete_slab_ending': False,
            'has_boiler_ending': True, 'has_air_source_heat_pump_ending': False, 'has_room_heaters_ending': False,
            'has_electric_storage_heaters_ending': False, 'has_warm_air_ending': False,
            'has_electric_underfloor_heating_ending': False, 'has_electric_ceiling_heating_ending': False,
            'has_community_scheme_ending': False, 'has_ground_source_heat_pump_ending': False,
            'has_no_system_present_ending': False, 'has_portable_electric_heaters_ending': False,
            'has_water_source_heat_pump_ending': False, 'has_electric_heat_pump_ending': False,
            'has_micro-cogeneration_ending': False, 'has_solar_assisted_heat_pump_ending': False,
            'has_exhaust_source_heat_pump_ending': False, 'has_community_heat_pump_ending': False,
            'has_electric_ending': False, 'has_mains_gas_ending': True, 'has_wood_logs_ending': False,
            'has_coal_ending': False, 'has_oil_ending': False, 'has_wood_pellets_ending': False,
            'has_anthracite_ending': False, 'has_dual_fuel_mineral_and_wood_ending': False,
            'has_smokeless_fuel_ending': False, 'has_lpg_ending': False, 'has_b30k_ending': False,
            'has_electricaire_ending': False, 'has_assumed_for_most_rooms_ending': False,
            'has_underfloor_heating_ending': False, 'thermostatic_control_ending': 'room thermostat',
            'charging_system_ending': 'Unknown', 'switch_system_ending': 'programmer', 'no_control_ending': 'Unknown',
            'dhw_control_ending': 'Unknown', 'community_heating_ending': 'Unknown',
            'multiple_room_thermostats_ending': False, 'auxiliary_systems_ending': 'Unknown', 'trvs_ending': 'Unknown',
            'rate_control_ending': 'Unknown', 'glazing_type_ending': 'single', 'fuel_type_ending': 'mains gas',
            'main-fuel_tariff_type_ending': 'Unknown', 'is_community_ending': False,
            'no_individual_heating_or_community_network_ending': False, 'complex_fuel_type_ending': 'Unknown',
            'sap_starting': 47, 'sap_ending': 47, 'heat_demand_starting': 478, 'heat_demand_ending': 478,
            'carbon_starting': 5.1, 'carbon_ending': 5.1, 'lighting_cost_starting': 91.0, 'lighting_cost_ending': 91.0,
            'heating_cost_starting': 1677.0, 'heating_cost_ending': 1677.0, 'hot_water_cost_starting': 161.0,
            'hot_water_cost_ending': 161.0, 'mechanical_ventilation_starting': 'natural',
            'mechanical_ventilation_ending': 'natural', 'secondheat_description_starting': 'None',
            'secondheat_description_ending': 'None', 'glazed_type_starting': 'not defined',
            'glazed_type_ending': 'not defined', 'multi_glaze_proportion_starting': 0.0,
            'multi_glaze_proportion_ending': 0.0, 'low_energy_lighting_starting': 100.0,
            'low_energy_lighting_ending': 100.0, 'number_open_fireplaces_starting': 0.0,
            'number_open_fireplaces_ending': 0.0, 'solar_water_heating_flag_starting': 'N',
            'solar_water_heating_flag_ending': 'N', 'photo_supply_starting': 0.0, 'photo_supply_ending': 0.0,
            'transaction_type_starting': 'rental', 'transaction_type_ending': 'rental',
            'energy_tariff_starting': 'dual', 'energy_tariff_ending': 'dual', 'extension_count_starting': 3.0,
            'extension_count_ending': 3.0, 'total_floor_area_starting': 61.0, 'total_floor_area_ending': 61.0,
            'floor_height_starting': 2.37, 'floor_height_ending': 2.37, 'hot_water_energy_eff_starting': 'Good',
            'hot_water_energy_eff_ending': 'Good', 'floor_energy_eff_starting': 'NO_RATING',
            'floor_energy_eff_ending': 'NO_RATING', 'windows_energy_eff_starting': 'Very Poor',
            'windows_energy_eff_ending': 'Very Poor', 'walls_energy_eff_starting': 'Very Poor',
            'walls_energy_eff_ending': 'Very Poor', 'sheating_energy_eff_starting': 'NO_RATING',
            'sheating_energy_eff_ending': 'NO_RATING', 'roof_energy_eff_starting': 'Very Poor',
            'roof_energy_eff_ending': 'Very Poor', 'mainheat_energy_eff_starting': 'Good',
            'mainheat_energy_eff_ending': 'Good', 'mainheatc_energy_eff_starting': 'Average',
            'mainheatc_energy_eff_ending': 'Average', 'lighting_energy_eff_starting': 'Very Good',
            'lighting_energy_eff_ending': 'Very Good', 'number_habitable_rooms_starting': 4.0,
            'number_habitable_rooms_ending': 4.0, 'number_heated_rooms_starting': 4.0,
            'number_heated_rooms_ending': 4.0, 'is_post_sap10_starting': False, 'is_post_sap10_ending': False,
            'lodgement_date_starting': '2024-07-21', 'lodgement_date_ending': '2024-07-21', 'days_to_starting': 3642,
            'days_to_ending': 3642, 'estimated_perimeter_starting': 23.430749027719962,
            'estimated_perimeter_ending': 23.430749027719962
        }

        assert starting_record == expected_base_difference_record

        # Simulate outcome
        property_9.adjust_difference_record_with_recommendations(
            property_recommendations, windows_rec
        )

        simulated_data = property_9.recommendations_scoring_data.copy()

        assert len(simulated_data) == 1

        expected_simulated_outcome = {
            'uprn': 200001041444, 'rdsap_change': 0, 'heat_demand_change': 0,
            'carbon_change': 0.0,
            'potential_energy_efficiency': 82.0, 'environment_impact_potential': 79.0,
            'energy_consumption_potential': 155.0, 'co2_emissions_potential': 1.7,
            'property_type': 'House',
            'built_form': 'Semi-Detached', 'constituency': 'E14000909',
            'number_habitable_rooms': 4.0,
            'number_heated_rooms': 4.0,
            'construction_age_band': 'England and Wales: before 1900',
            'fixed_lighting_outlets_count': 7.0, 'walls_thermal_transmittance': 1.7,
            'walls_thermal_transmittance_unit': 'Unknown', 'is_cavity_wall': False,
            'is_filled_cavity': False,
            'is_solid_brick': True, 'is_system_built': False, 'is_timber_frame': False,
            'is_granite_or_whinstone': False,
            'is_as_built': True, 'is_cob': False, 'walls_is_assumed': True,
            'is_sandstone_or_limestone': False,
            'is_park_home': False, 'walls_insulation_thickness': 'none',
            'external_insulation': False,
            'internal_insulation': False, 'floor_thermal_transmittance': 0.96,
            'is_to_unheated_space': False,
            'is_to_external_air': False, 'is_suspended': False, 'is_solid': True,
            'another_property_below': False,
            'floor_insulation_thickness': 'none', 'roof_thermal_transmittance': 2.3,
            'is_pitched': True,
            'is_roof_room': False, 'is_loft': False, 'is_flat': False, 'is_thatched': False,
            'is_at_rafters': False,
            'has_dwelling_above': False, 'roof_insulation_thickness': 'none',
            'heater_type': 'Unknown',
            'system_type': 'from main system', 'thermostat_characteristics': 'Unknown',
            'heating_scope': 'Unknown',
            'energy_recovery': 'Unknown', 'hotwater_tariff_type': 'Unknown',
            'extra_features': 'Unknown',
            'chp_systems': 'Unknown', 'distribution_system': 'Unknown',
            'no_system_present': 'Unknown',
            'appliance': 'Unknown', 'has_radiators': True, 'has_fan_coil_units': False,
            'has_pipes_in_screed_above_insulation': False,
            'has_pipes_in_insulated_timber_floor': False,
            'has_pipes_in_concrete_slab': False, 'has_boiler': True,
            'has_air_source_heat_pump': False,
            'has_room_heaters': False, 'has_electric_storage_heaters': False,
            'has_warm_air': False,
            'has_electric_underfloor_heating': False, 'has_electric_ceiling_heating': False,
            'has_community_scheme': False, 'has_ground_source_heat_pump': False,
            'has_no_system_present': False,
            'has_portable_electric_heaters': False, 'has_water_source_heat_pump': False,
            'has_electric_heat_pump': False,
            'has_micro-cogeneration': False, 'has_solar_assisted_heat_pump': False,
            'has_exhaust_source_heat_pump': False,
            'has_community_heat_pump': False, 'has_electric': False, 'has_mains_gas': True,
            'has_wood_logs': False,
            'has_coal': False, 'has_oil': False, 'has_wood_pellets': False,
            'has_anthracite': False,
            'has_dual_fuel_mineral_and_wood': False, 'has_smokeless_fuel': False,
            'has_lpg': False, 'has_b30k': False,
            'has_electricaire': False, 'has_assumed_for_most_rooms': False,
            'has_underfloor_heating': False,
            'thermostatic_control': 'room thermostat', 'charging_system': 'Unknown',
            'switch_system': 'programmer',
            'no_control': 'Unknown', 'dhw_control': 'Unknown', 'community_heating': 'Unknown',
            'multiple_room_thermostats': False, 'auxiliary_systems': 'Unknown',
            'trvs': 'Unknown',
            'rate_control': 'Unknown', 'glazing_type': 'single', 'fuel_type': 'mains gas',
            'main-fuel_tariff_type': 'Unknown', 'is_community': False,
            'no_individual_heating_or_community_network': False,
            'complex_fuel_type': 'Unknown',
            'walls_thermal_transmittance_ending': 1.7,
            'walls_thermal_transmittance_unit_ending': 'Unknown',
            'is_filled_cavity_ending': False, 'is_as_built_ending': True,
            'walls_is_assumed_ending': True,
            'is_park_home_ending': False, 'walls_insulation_thickness_ending': 'none',
            'external_insulation_ending': False, 'internal_insulation_ending': False,
            'floor_thermal_transmittance_ending': 0.96,
            'floor_insulation_thickness_ending': 'none',
            'roof_thermal_transmittance_ending': 2.3, 'is_at_rafters_ending': False,
            'roof_insulation_thickness_ending': 'none', 'heater_type_ending': 'Unknown',
            'system_type_ending': 'from main system',
            'thermostat_characteristics_ending': 'Unknown',
            'heating_scope_ending': 'Unknown', 'energy_recovery_ending': 'Unknown',
            'hotwater_tariff_type_ending': 'Unknown', 'extra_features_ending': 'Unknown',
            'chp_systems_ending': 'Unknown',
            'distribution_system_ending': 'Unknown', 'no_system_present_ending': 'Unknown',
            'appliance_ending': 'Unknown',
            'has_radiators_ending': True, 'has_fan_coil_units_ending': False,
            'has_pipes_in_screed_above_insulation_ending': False,
            'has_pipes_in_insulated_timber_floor_ending': False,
            'has_pipes_in_concrete_slab_ending': False, 'has_boiler_ending': True,
            'has_air_source_heat_pump_ending': False, 'has_room_heaters_ending': False,
            'has_electric_storage_heaters_ending': False, 'has_warm_air_ending': False,
            'has_electric_underfloor_heating_ending': False,
            'has_electric_ceiling_heating_ending': False,
            'has_community_scheme_ending': False, 'has_ground_source_heat_pump_ending': False,
            'has_no_system_present_ending': False,
            'has_portable_electric_heaters_ending': False,
            'has_water_source_heat_pump_ending': False,
            'has_electric_heat_pump_ending': False,
            'has_micro-cogeneration_ending': False,
            'has_solar_assisted_heat_pump_ending': False,
            'has_exhaust_source_heat_pump_ending': False,
            'has_community_heat_pump_ending': False,
            'has_electric_ending': False, 'has_mains_gas_ending': True,
            'has_wood_logs_ending': False,
            'has_coal_ending': False, 'has_oil_ending': False,
            'has_wood_pellets_ending': False,
            'has_anthracite_ending': False, 'has_dual_fuel_mineral_and_wood_ending': False,
            'has_smokeless_fuel_ending': False, 'has_lpg_ending': False,
            'has_b30k_ending': False,
            'has_electricaire_ending': False, 'has_assumed_for_most_rooms_ending': False,
            'has_underfloor_heating_ending': False,
            'thermostatic_control_ending': 'room thermostat',
            'charging_system_ending': 'Unknown', 'switch_system_ending': 'programmer',
            'no_control_ending': 'Unknown',
            'dhw_control_ending': 'Unknown', 'community_heating_ending': 'Unknown',
            'multiple_room_thermostats_ending': False, 'auxiliary_systems_ending': 'Unknown',
            'trvs_ending': 'Unknown',
            'rate_control_ending': 'Unknown', 'glazing_type_ending': 'double',
            'fuel_type_ending': 'mains gas',
            'main-fuel_tariff_type_ending': 'Unknown', 'is_community_ending': False,
            'no_individual_heating_or_community_network_ending': False,
            'complex_fuel_type_ending': 'Unknown',
            'sap_starting': 47, 'sap_ending': 47, 'heat_demand_starting': 478,
            'heat_demand_ending': 478,
            'carbon_starting': 5.1, 'carbon_ending': 5.1, 'lighting_cost_starting': 91.0,
            'lighting_cost_ending': 91.0,
            'heating_cost_starting': 1677.0, 'heating_cost_ending': 1677.0,
            'hot_water_cost_starting': 161.0,
            'hot_water_cost_ending': 161.0, 'mechanical_ventilation_starting': 'natural',
            'mechanical_ventilation_ending': 'natural',
            'secondheat_description_starting': 'None',
            'secondheat_description_ending': 'None', 'glazed_type_starting': 'not defined',
            'glazed_type_ending': 'double glazing installed during or after 2002',
            'multi_glaze_proportion_starting': 0.0,
            'multi_glaze_proportion_ending': 100, 'low_energy_lighting_starting': 100.0,
            'low_energy_lighting_ending': 100.0, 'number_open_fireplaces_starting': 0.0,
            'number_open_fireplaces_ending': 0.0, 'solar_water_heating_flag_starting': 'N',
            'solar_water_heating_flag_ending': 'N', 'photo_supply_starting': 0.0,
            'photo_supply_ending': 0.0,
            'transaction_type_starting': 'rental', 'transaction_type_ending': 'rental',
            'energy_tariff_starting': 'dual',
            'energy_tariff_ending': 'dual', 'extension_count_starting': 3.0,
            'extension_count_ending': 3.0,
            'total_floor_area_starting': 61.0, 'total_floor_area_ending': 61.0,
            'floor_height_starting': 2.37,
            'floor_height_ending': 2.37, 'hot_water_energy_eff_starting': 'Good',
            'hot_water_energy_eff_ending': 'Good',
            'floor_energy_eff_starting': 'NO_RATING', 'floor_energy_eff_ending': 'NO_RATING',
            'windows_energy_eff_starting': 'Very Poor', 'windows_energy_eff_ending': 'Good',
            'walls_energy_eff_starting': 'Very Poor', 'walls_energy_eff_ending': 'Very Poor',
            'sheating_energy_eff_starting': 'NO_RATING',
            'sheating_energy_eff_ending': 'NO_RATING',
            'roof_energy_eff_starting': 'Very Poor', 'roof_energy_eff_ending': 'Very Poor',
            'mainheat_energy_eff_starting': 'Good', 'mainheat_energy_eff_ending': 'Good',
            'mainheatc_energy_eff_starting': 'Average',
            'mainheatc_energy_eff_ending': 'Average',
            'lighting_energy_eff_starting': 'Very Good',
            'lighting_energy_eff_ending': 'Very Good',
            'number_habitable_rooms_starting': 4.0, 'number_habitable_rooms_ending': 4.0,
            'number_heated_rooms_starting': 4.0, 'number_heated_rooms_ending': 4.0,
            'is_post_sap10_starting': False,
            'is_post_sap10_ending': False, 'lodgement_date_starting': '2024-07-21',
            'lodgement_date_ending': '2024-07-21',
            'days_to_starting': 3642, 'days_to_ending': 4189,
            'estimated_perimeter_starting': 23.430749027719962,
            'estimated_perimeter_ending': 23.430749027719962, 'has_glazing_ending': True,
            'glazing_coverage_ending': 'full', 'id': '1+1'
        }

        # Make sure all keys are the same, apart from days_to_ending
        assert all([v == expected_simulated_outcome[k] for k, v in simulated_data[0].items() if k != "days_to_ending"])

        # has_glazing_ending and glazing_coverage_ending are not in the starting record - test for this in case it
        # changes
        assert "has_glazing_ending" not in starting_record
        assert "glazing_coverage_ending" not in starting_record

        # Check which keys are different
        different = []
        for k in simulated_data[0].keys():
            if k in ["id", 'has_glazing_ending', 'glazing_coverage_ending', 'days_to_ending']:
                continue
            if simulated_data[0][k] != starting_record[k]:
                different.append(
                    {
                        "variable": k,
                        "starting": starting_record[k],
                        "simulated": simulated_data[0][k],

                    }
                )

        expected_different = [
            {'variable': 'glazing_type_ending', 'starting': 'single', 'simulated': 'double'},
            {'variable': 'glazed_type_ending', 'starting': 'not defined',
             'simulated': 'double glazing installed during or after 2002'},
            {'variable': 'multi_glaze_proportion_ending', 'starting': 0.0, 'simulated': 100},
            {'variable': 'windows_energy_eff_ending', 'starting': 'Very Poor', 'simulated': 'Good'},
        ]

        assert different == expected_different
