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:

    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.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 0,
            "uprn": 0
        }
        property_1 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_1.windows = {
            'original_description': 'Single glazed', 'has_glazing': False, 'glazing_coverage': 'full',
            'glazing_type': 'single',
            'no_data': False
        }
        property_1.number_of_windows = 7

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

        assert not recommender.recommendation

        recommender.recommend()

        assert recommender.recommendation == [
            {'parts': [], 'type': 'windows_glazing', 'description': 'Install double glazing to all windows',
             'starting_u_value': None, 'new_u_value': None, 'sap_points': None, 'total': 5721.943248,
             'subtotal': 4768.28604, 'vat': 953.6572080000001, 'contingency': 340.59186, 'preliminaries': 340.59186,
             'material': 1275.75, 'profit': 681.18372, 'labour_hours': 45.5, 'labour_cost': 994.8624,
             'labour_days': 2.84375, 'is_secondary_glazing': False}]

    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.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 33,
            "uprn": 0
        }
        property_2 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_2.windows = {'original_description': 'Mostly double glazing', 'has_glazing': True,
                              'glazing_coverage': 'most',
                              'glazing_type': 'double', 'no_data': False}
        property_2.number_of_windows = 7

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

        assert not recommender2.recommendation

        recommender2.recommend()

        assert recommender2.recommendation == [
            {'parts': [], 'type': 'windows_glazing', 'description': 'Install double glazing to the remaining windows',
             'starting_u_value': None, 'new_u_value': None, 'sap_points': None, 'total': 4087.10232,
             'subtotal': 3405.9186, 'vat': 681.18372, 'contingency': 243.2799, 'preliminaries': 243.2799,
             'material': 911.25, 'profit': 486.5598, 'labour_hours': 32.5, 'labour_cost': 710.6160000000001,
             'labour_days': 2.03125, 'is_secondary_glazing': False}]

    def test_fully_double_glazed(self):
        """
        This property has full double glazing so we shouldn't recommend anything
        :return:
        """
        epc_record = EPCRecord()
        epc_record.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 100,
            "uprn": 0
        }
        property_3 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_3.windows = {'original_description': 'Fully double glazed', 'has_glazing': True,
                              'glazing_coverage': 'full',
                              'glazing_type': 'double', 'no_data': False}
        property_3.number_of_windows = 7

        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.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 100,
            "uprn": 0
        }
        property_4 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_4.windows = {'original_description': 'Full secondary glazing', 'has_glazing': True,
                              'glazing_coverage': 'full',
                              'glazing_type': 'secondary', 'no_data': False}
        property_4.number_of_windows = 7

        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.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 50,
            "uprn": 0
        }
        property_5 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_5.windows = {'original_description': 'Partial secondary glazing', 'has_glazing': True,
                              'glazing_coverage': 'partial',
                              'glazing_type': 'secondary', 'no_data': False}
        property_5.number_of_windows = 7

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

        assert not recommender5.recommendation

        recommender5.recommend()

        assert recommender5.recommendation == [
            {'parts': [], 'type': 'windows_glazing',
             'description': 'Install secondary glazing to the remaining windows',
             'starting_u_value': None, 'new_u_value': None, 'sap_points': None, 'total': 1089.893952,
             'subtotal': 908.24496, 'vat': 181.64899200000002, 'contingency': 64.87464, 'preliminaries': 64.87464,
             'material': 729.0, 'profit': 129.74928, 'labour_hours': 13.0, 'labour_cost': 568.4928,
             'labour_days': 0.8125, 'is_secondary_glazing': True}]

    def test_single_glazed_restricted_measures(self):
        epc_record = EPCRecord()
        epc_record.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 0,
            "uprn": 0
        }

        property_6 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_6.windows = {'original_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

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

        assert not recommender6.recommendation

        recommender6.recommend()

        assert recommender6.recommendation == [
            {'parts': [], 'type': 'windows_glazing',
             'description': 'Install secondary glazing to all windows. Secondary '
                            'glazing recommended due to herigate building status',
             'starting_u_value': None, 'new_u_value': None, 'sap_points': None,
             'total': 1907.314416, 'subtotal': 1589.42868, 'vat': 317.885736,
             'contingency': 113.53062, 'preliminaries': 113.53062,
             'material': 1275.75, 'profit': 227.06124, 'labour_hours': 22.75,
             'labour_cost': 994.8624, 'labour_days': 1.421875, 'is_secondary_glazing': True}
        ]

    def test_full_triple_glazed(self):
        epc_record = EPCRecord()
        epc_record.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 100,
            "uprn": 0
        }
        property_7 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_7.windows = {'original_description': 'Fully triple glazed', 'has_glazing': True,
                              'glazing_coverage': 'full',
                              'glazing_type': 'triple', 'no_data': False}
        property_7.number_of_windows = 7

        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 should just recommend double glazing to the remaining windows, since it's a cheaper option
        """
        epc_record = EPCRecord()
        epc_record.prepared_epc = {
            "county": "Wychavon",
            "multi-glaze-proportion": 80,
            "uprn": 1
        }
        property_8 = Property(
            id=1,
            postcode='1',
            address='1',
            epc_record=epc_record
        )
        property_8.windows = {'original_description': 'Mostly triple glazing', 'has_glazing': True,
                              'glazing_coverage': 'most',
                              'glazing_type': 'triple', 'no_data': False}
        property_8.number_of_windows = 7

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

        assert not recommender8.recommendation

        recommender8.recommend()

        assert recommender8.recommendation == [
            {'parts': [], 'type': 'windows_glazing', 'description': 'Install double glazing to the remaining windows',
             'starting_u_value': None, 'new_u_value': None, 'sap_points': None, 'total': 1634.840928,
             'subtotal': 1362.36744, 'vat': 272.47348800000003, 'contingency': 97.31196, 'preliminaries': 97.31196,
             'material': 364.5, 'profit': 194.62392, 'labour_hours': 13.0, 'labour_cost': 284.2464,
             'labour_days': 0.8125, 'is_secondary_glazing': False}]
