import enum

from sqlalchemy import Column, Integer, String, Float, Enum, TIMESTAMP, Boolean
from sqlalchemy.sql import func

from backend.app.db.base import Base


class MaterialType(enum.Enum):
    suspended_floor_insulation = "suspended_floor_insulation"
    solid_floor_insulation = "solid_floor_insulation"
    external_wall_insulation = "external_wall_insulation"
    internal_wall_insulation = "internal_wall_insulation"
    cavity_wall_insulation = "cavity_wall_insulation"
    mechanical_ventilation = "mechanical_ventilation"
    loft_insulation = "loft_insulation"
    exposed_floor_insulation = "exposed_floor_insulation"
    flat_roof_insulation = "flat_roof_insulation"
    room_roof_insulation = "room_roof_insulation"
    windows_glazing = "windows_glazing"
    secondary_glazing = "secondary_glazing"
    double_glazing = "double_glazing"
    cavity_wall_extraction = "cavity_wall_extraction"

    iwi_wall_demolition = "iwi_wall_demolition"
    iwi_vapour_barrier = "iwi_vapour_barrier"
    iwi_redecoration = "iwi_redecoration"
    suspended_floor_demolition = "suspended_floor_demolition"
    suspended_floor_redecoration = "suspended_floor_redecoration"
    suspended_floor_vapour_barrier = "suspended_floor_vapour_barrier"
    solid_floor_demolition = "solid_floor_demolition"
    solid_floor_preparation = "solid_floor_preparation"
    solid_floor_vapour_barrier = "solid_floor_vapour_barrier"
    solid_floor_redecoration = "solid_floor_redecoration"
    ewi_wall_demolition = "ewi_wall_demolition"
    ewi_wall_preparation = "ewi_wall_preparation"
    ewi_wall_redecoration = "ewi_wall_redecoration"
    low_energy_lighting_installation = "low_energy_lighting_installation"
    flat_roof_preparation = "flat_roof_preparation"
    flat_roof_vapour_barrier = "flat_roof_vapour_barrier"
    flat_roof_waterproofing = "flat_roof_waterproofing"
    trickle_vent = "trickle_vent"
    door_undercut = "door_undercut"
    solar_pv = "solar_pv"
    solar_battery = "solar_battery"
    scaffolding = "scaffolding"
    # Heating systems
    high_heat_retention_storage_heaters = "high_heat_retention_storage_heaters"
    air_soruce_heat_pump = "air_soruce_heat_pump"
    boiler_upgrade = "boiler_upgrade"
    sealing_fireplace = "sealing_fireplace"
    roomstat_programmer_trvs = "roomstat_programmer_trvs"
    time_temperature_zone_control = "time_temperature_zone_control"


class DepthUnit(enum.Enum):
    mm = "mm"


class SizeUnit(enum.Enum):
    # ["kWp", "kW", "watt", "storey"]
    kWp = "kWp"
    kW = "kW"
    watt = "watt"
    storey = "storey"


class CostUnit(enum.Enum):
    gbp_sq_meter = "gbp_sq_meter"
    gbp_per_unit = "gbp_per_unit"
    gbp_per_m2 = "gbp_per_m2"
    gbp_per_m = "gbp_per_m"


class RValueUnit(enum.Enum):
    square_meter_kelvin_per_watt = "square_meter_kelvin_per_watt"


class ThermalConductivityUnit(enum.Enum):
    watt_per_meter_kelvin = "watt_per_meter_kelvin"


class Material(Base):
    __tablename__ = 'material'

    id = Column(Integer, primary_key=True, autoincrement=True)
    type = Column(Enum(MaterialType, values_callable=lambda x: [e.value for e in x], create_constraint=False),
                  nullable=False)

    description = Column(String, nullable=False)
    depth = Column(String)  # You may want to use a specific JSON type depending on the database
    depth_unit = Column(Enum(DepthUnit, values_callable=lambda x: [e.value for e in x]), nullable=False)
    cost = Column(String)
    cost_unit = Column(Enum(CostUnit, values_callable=lambda x: [e.value for e in x]), nullable=False)
    r_value_per_mm = Column(Float)
    r_value_unit = Column(Enum(RValueUnit, values_callable=lambda x: [e.value for e in x]), nullable=False)
    thermal_conductivity = Column(Float)
    thermal_conductivity_unit = Column(
        Enum(ThermalConductivityUnit, values_callable=lambda x: [e.value for e in x]),
        nullable=False
    )
    link = Column(String)
    created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
    is_active = Column(Boolean, nullable=False, default=True)

    prime_material_cost = Column(Float)
    material_cost = Column(Float)
    labour_cost = Column(Float)
    labour_hours_per_unit = Column(Float)
    plant_cost = Column(Float)
    total_cost = Column(Float)
    notes = Column(String)
    is_installer_quote = Column(Boolean, nullable=False, default=False)
    innovation_rate = Column(Float, default=0.0)
    size = Column(Float)
    size_unit = Column(
        Enum(SizeUnit, values_callable=lambda x: [e.value for e in x]), nullable=True
    )
    includes_scaffolding = Column(Boolean, default=False)
    includes_battery = Column(Boolean, default=False)
    battery_size = Column(Float)
