from dataclasses import dataclass
from datetime import date
from typing import List, Optional


@dataclass
class SurveyorInfo:
    surveyor_code: str
    name: str
    title: str
    tel_number: str
    survey_reference: str
    my_reference: Optional[str] = None


@dataclass
class PropertyDetails:
    rdsap_version: str
    reference_number: str
    lodgement_required: bool
    regs_region: str
    epc_language: str
    postcode: str
    region: str
    street: str
    town: str
    tenure: str
    transaction_type: str
    inspection_date: date
    process_date: date
    epc_exists: bool
    uprn: Optional[str] = None
    house_name: Optional[str] = None
    house_number: Optional[str] = None
    locality: Optional[str] = None
    county: Optional[str] = None


@dataclass
class FloorDimension:
    name: str  # e.g. "Lowest Floor"
    area_m2: float
    room_height_m: float
    heat_loss_perimeter_m: float
    party_wall_length_m: float


@dataclass
class BuildingPartDimensions:
    dimension_type: str  # e.g. "Internal"
    floors: List[FloorDimension]


@dataclass
class WallDetails:
    wall_type: str  # e.g. "CA Cavity"
    insulation: str  # e.g. "F Filled Cavity"
    thickness_unknown: bool
    u_value_known: bool
    party_wall_type: str  # e.g. "U Unable to determine"
    thickness_mm: Optional[int] = None


@dataclass
class RoofDetails:
    roof_type: str  # e.g. "PA Pitched (slates/tiles), access to loft"
    insulation: str  # e.g. "J Joists"
    u_value_known: bool
    insulation_thickness_mm: Optional[int] = None


@dataclass
class FloorDetails:
    location: str  # e.g. "G Ground floor"
    floor_type: str  # e.g. "N Suspended, not timber"
    insulation: str  # e.g. "A As built"
    u_value_known: bool
    default_u_value: Optional[float] = None


@dataclass
class Window:
    width_m: float
    height_m: float
    area_m2: float
    glazing_type: str
    frame_factor: float
    building_part: str
    location: str
    orientation: str
    data_source: str
    u_value: float
    g_value: float
    draught_proofed: bool
    permanent_shutters: str  # e.g. "None"
    frame_type: Optional[str] = None
    glazing_gap: Optional[str] = None


@dataclass
class VentilationAndCooling:
    open_chimneys_count: int
    open_flues_count: int
    open_chimneys_closed_fire_count: int
    solid_fuel_boiler_flues_count: int
    other_heater_flues_count: int
    blocked_chimneys_count: int
    extract_fans_count: int
    passive_vents_count: int
    flueless_gas_fires_count: int
    fixed_space_cooling: bool
    draught_lobby: str  # e.g. "Not present"
    mechanical_ventilation: bool
    pressure_test_method: str  # e.g. "Not available"


@dataclass
class Lighting:
    total_bulbs: int
    led_cfl_count_known: bool
    led_count: int
    cfl_count: int
    incandescent_count: int
    low_energy_count: int = 0


@dataclass
class MainHeating:
    heat_emitter: str  # e.g. "Radiators"
    fuel_type: str  # e.g. "Mains gas"
    flue_type: str  # e.g. "Balanced"
    fan_assisted_flue: bool
    design_flow_temperature: str  # e.g. "Unknown"
    heating_controls_ees: str  # e.g. "CBE"
    heating_controls_sap: (
        str  # e.g. "SAP code 2106, Programmer, room thermostat and TRVs"
    )
    percentage_of_heat: int
    pcdf_boiler_reference: Optional[str] = (
        None  # e.g. "17742 Potterton, Promax 33 Combi ErP, 88.30%"
    )
    heat_pump_age: Optional[str] = None


@dataclass
class Meters:
    electricity_meter_type: str  # e.g. "Single"
    main_gas: bool
    electricity_smart_meter: bool
    gas_smart_meter: bool


@dataclass
class WaterHeating:
    water_heating_code: str  # e.g. "HWP"
    water_heating_sap_code: int
    water_heating_fuel_type: str
    hot_water_cylinder_present: bool


@dataclass
class Shower:
    shower_number: int
    outlet_type: str
    connected: str  # e.g. "None"


@dataclass
class BathsAndShowers:
    number_of_baths: int
    number_of_baths_connected: int
    showers: List[Shower]


@dataclass
class Renewables:
    solar_water_heating: bool
    wwhrs_present: bool
    flue_gas_heat_recovery_present: bool
    photovoltaic_panel: str  # e.g. "None"
    export_capable_meter: bool
    wind_turbine_present: bool
    wind_turbines_terrain_type: str
    hydro_electricity_generated_kwh: float


@dataclass
class ElmhurstSiteNotes:
    surveyor_info: SurveyorInfo
    property_details: PropertyDetails

    # Summary Information
    current_sap_rating: int
    potential_sap_rating: int
    current_ei_rating: int
    potential_ei_rating: int
    co2_emissions_current_t: float

    # Section 1.0
    property_type: str  # e.g. "B Bungalow"
    attachment: str  # e.g. "E End-Terrace"

    # Section 2.0
    number_of_storeys: int
    habitable_rooms: int
    heated_habitable_rooms: int

    # Section 3.0
    construction_age_band: str  # e.g. "D 1950-1966"

    # Section 4.0
    dimensions: BuildingPartDimensions

    # Section 5.0
    has_conservatory: bool

    # Sections 7.0–9.0
    walls: WallDetails
    roof: RoofDetails
    floor: FloorDetails

    # Section 10.0
    door_count: int
    insulated_door_count: int

    # Section 11.0
    windows: List[Window]
    draught_proofing_percent: int

    # Section 12.0
    ventilation: VentilationAndCooling

    # Section 13.0
    lighting: Lighting

    # Section 14.0–14.2
    main_heating: MainHeating
    meters: Meters

    # Section 15.0
    water_heating: WaterHeating

    # Section 1x.0
    baths_and_showers: BathsAndShowers

    # Sections 16.0–22.0
    renewables: Renewables
