from dataclasses import dataclass
import datatypes.epc as epc_datatypes
from typing import Optional, Union


@dataclass(slots=True)
class Address:
    # address: Optional[str]
    # full_address: Optional[str]
    # property_type: Optional[str]
    # built_form: Optional[str]
    # estimated: bool

    # New fields
    uprn: Optional[int]
    landlord_property_id: Optional[str]
    address_1: str
    address_2: Optional[str]
    address_3: Optional[str]
    full_address: str
    postcode: str
    landlord_total_floor_area_m2: Union[float, None]
    # Property components
    landlord_property_type: Optional[epc_datatypes.property_type_built_form.PropertyType]
    landlord_built_form: Optional[epc_datatypes.property_type_built_form.BuiltForm]
    landlord_wall_construction: Optional[epc_datatypes.walls.EpcWallDescriptions]
    landlord_roof_construction: Optional[epc_datatypes.roof.EpcRoofDescriptions]
    landlord_floor_construction: Optional[epc_datatypes.floor.EpcFloorDescriptions]
    landlord_windows_type: Optional[epc_datatypes.windows.EpcWindowDescriptions]
    landlord_heating_system: Optional[epc_datatypes.main_heating.EpcHeatingSystems]
    landlord_fuel_type: Optional[epc_datatypes.fuel.EpcFuel]
    landlord_heating_controls: Optional[epc_datatypes.heating_controls.EpcHeatingControls]
    landlord_hot_water_system: Optional[epc_datatypes.hotwater.EpcHotWaterSystems]
    # Efficiency
    landlord_wall_efficiency: Optional[epc_datatypes.efficiency.EpcEfficiency]
    landlord_roof_efficiency: Optional[epc_datatypes.efficiency.EpcEfficiency]
    landlord_windows_efficiency: Optional[epc_datatypes.efficiency.EpcEfficiency]
    landlord_heating_efficiency: Optional[epc_datatypes.efficiency.EpcEfficiency]
    landlord_heating_controls_efficiency: Optional[epc_datatypes.efficiency.EpcEfficiency]
    landlord_hot_water_efficiency: Optional[epc_datatypes.efficiency.EpcEfficiency]

    # Additionals
    landlord_has_sloping_ceiling: Optional[bool]
    landlord_multi_glaze_proportion: Optional[float]
    landlord_construction_age_band: Optional[epc_datatypes.construction_age_band.EpcConstructionAgeBand]

    # Additional address data, associated to a standardised asset list
    # domna_full_address: Optional[str]
    # domna_address_1: Optional[str]

    # Identifiers to handle the case where we have erroneous matches based on UPRN due to probelmatic EPC data
    lmk_key: Optional[str]
    epc_certificate_number: Optional[str]

    @property
    def request_data(self) -> dict[str, Optional[str]]:
        """
        Canonical request payload for downstream services.
        """
        data = {
            "uprn": self.uprn,
            "landlord_property_id": self.landlord_property_id,
            "postcode": self.postcode,
            "address1": self.address_1,
            "full_address": self.full_address,
        }

        # Drop nulls
        return {k: v for k, v in data.items() if v is not None}
