import pytest
from recommendations.SolarPvRecommendations import SolarPvRecommendations
from backend.Property import Property
from etl.epc.Record import EPCRecord
import pandas as pd
import numpy as np


class TestSolarPvRecommendations:
    @pytest.fixture
    def property_instance_invalid_type(self):
        # Setup the property_instance with an invalid property type
        epc_record = EPCRecord()
        epc_record.prepared_epc = {
            "property-type": "InvalidType", "county": "Broxbourne", "photo-supply": None
        }
        property_instance_invalid_type = Property(id=1, address="", postcode="", epc_record=epc_record)
        property_instance_invalid_type.roof = {"is_flat": False, "is_pitched": False, "is_roof_room": False}
        return property_instance_invalid_type

    @pytest.fixture
    def property_instance_invalid_roof(self):
        # Setup the property_instance with invalid roof type
        epc_record = EPCRecord()
        epc_record.prepared_epc = {
            "county": "Huntingdonshire", "property-type": "House", "photo-supply": None
        }
        property_instance_invalid_roof = Property(id=1, address="", postcode="", epc_record=epc_record)
        property_instance_invalid_roof.roof = {
            "is_flat": False, "is_pitched": False, "is_roof_room": False, "thermal_transmittance": None
        }
        return property_instance_invalid_roof

    @pytest.fixture
    def property_instance_has_solar_pv(self):
        # Setup the property_instance without existing solar pv
        epc_record = EPCRecord()
        epc_record.prepared_epc = {"photo-supply": "40", "county": "Huntingdonshire",
                                   "property-type": "House"}
        property_instance_has_solar_pv = Property(id=1, address="", postcode="", epc_record=epc_record)
        property_instance_has_solar_pv.roof = {"is_flat": True, "thermal_transmittance": None}
        return property_instance_has_solar_pv

    @pytest.fixture
    def property_instance_valid_all(self):
        # Setup a valid property_instance that passes all conditions
        epc_record = EPCRecord()
        epc_record.prepared_epc = {"property-type": "House", "photo-supply": None, "county": "Huntingdonshire"}
        property_instance_valid_all = Property(id=1, address="", postcode="", epc_record=epc_record)
        property_instance_valid_all.roof_area = 40
        property_instance_valid_all.number_of_floors = 2
        property_instance_valid_all.roof = {"is_flat": True, "thermal_transmittance": None}
        property_instance_valid_all.solar_panel_configuration = {
            "panel_performance": pd.DataFrame(
                [
                    {
                        "panneled_roof_area": 20,
                        "n_panels": 10,
                        "array_wattage": 4000,
                        "initial_ac_kwh_per_year": 3800
                    }
                ]
            )
        }

        return property_instance_valid_all

    def test_invalid_property_type(self, property_instance_invalid_type):
        solar_pv = SolarPvRecommendations(property_instance_invalid_type)
        solar_pv.recommend(phase=0)
        assert not solar_pv.recommendation

    def test_invalid_roof_type(self, property_instance_invalid_roof):
        solar_pv = SolarPvRecommendations(property_instance_invalid_roof)
        solar_pv.recommend(phase=0)
        assert not solar_pv.recommendation

    def test_existing_solar_pv(self, property_instance_has_solar_pv):
        solar_pv = SolarPvRecommendations(property_instance_has_solar_pv)
        solar_pv.recommend(phase=0)
        assert not solar_pv.recommendation

    def test_valid_all_conditions(self, property_instance_valid_all):
        solar_pv = SolarPvRecommendations(property_instance_valid_all)
        solar_pv.recommend(phase=0)
        assert len(solar_pv.recommendation) == 2
        assert solar_pv.recommendation == [
            {'phase': 0, 'parts': [], 'type': 'solar_pv', 'measure_type': 'solar_pv',
             'description': 'Install a 4.0 kilowatt-peak (kWp) solar panel system.', 'starting_u_value': None,
             'new_u_value': None, 'sap_points': np.float64(10.0), 'already_installed': False,
             'total': 6013.139999999999, 'subtotal': 5010.95, 'vat': 0, 'labour_hours': 48, 'labour_days': 2,
             'photo_supply': np.float64(50.0), 'has_battery': False, 'initial_ac_kwh_per_year': np.int64(3800),
             'description_simulation': {'photo-supply': np.float64(50.0)}},
            {'phase': 0, 'parts': [], 'type': 'solar_pv', 'measure_type': 'solar_pv',
             'description': 'Install a 4.0 kilowatt-peak (kWp) solar panel system, with a battery.',
             'starting_u_value': None, 'new_u_value': None, 'sap_points': np.float64(10.0), 'already_installed': False,
             'total': 10537.008, 'subtotal': 8780.84, 'vat': 0, 'labour_hours': 48, 'labour_days': 2,
             'photo_supply': np.float64(50.0), 'has_battery': True, 'initial_ac_kwh_per_year': np.int64(3800),
             'description_simulation': {'photo-supply': np.float64(50.0)}}
        ]
