from sqlalchemy import Column, BigInteger, String, Float, Boolean, TIMESTAMP, ForeignKey, Enum
from sqlalchemy.orm import declarative_base
from sqlalchemy.sql import func
from backend.app.db.models.portfolio import Portfolio, PropertyModel
from backend.app.db.models.materials import Material
from datatypes.enums import QuantityUnits

Base = declarative_base()


class Recommendation(Base):
    __tablename__ = 'recommendation'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    property_id = Column(BigInteger, ForeignKey(PropertyModel.id), nullable=False)
    created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
    type = Column(String, nullable=False)
    measure_type = Column(String)
    description = Column(String, nullable=False)
    estimated_cost = Column(Float)
    default = Column(Boolean, nullable=False)
    starting_u_value = Column(Float)
    new_u_value = Column(Float)
    sap_points = Column(Float)
    heat_demand = Column(Float)
    kwh_savings = Column(Float)
    co2_equivalent_savings = Column(Float)
    energy_savings = Column(Float)
    energy_cost_savings = Column(Float)
    property_valuation_increase = Column(Float)
    rental_yield_increase = Column(Float)
    total_work_hours = Column(Float)
    labour_days = Column(Float)
    already_installed = Column(Boolean, nullable=False, default=False)


class RecommendationMaterials(Base):
    __tablename__ = 'recommendation_materials'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    recommendation_id = Column(BigInteger, ForeignKey('recommendation.id'), nullable=False)
    material_id = Column(BigInteger, ForeignKey(Material.id), nullable=False)
    created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
    depth = Column(Float, nullable=False)
    quantity = Column(Float, nullable=False)
    quantity_unit = Column(Enum(QuantityUnits, values_callable=lambda x: [e.value for e in x]), nullable=False)
    estimated_cost = Column(Float, nullable=False)


class Plan(Base):
    __tablename__ = 'plan'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String, nullable=True, default="")
    portfolio_id = Column(BigInteger, ForeignKey(Portfolio.id), nullable=False)
    property_id = Column(BigInteger, ForeignKey(PropertyModel.id), nullable=False)
    scenario_id = Column(BigInteger, ForeignKey('scenario.id'))  # Doesn't have to be linked to a scenario
    created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
    is_default = Column(Boolean, nullable=False)
    valuation_increase_lower_bound = Column(Float)
    valuation_increase_upper_bound = Column(Float)
    valuation_increase_average = Column(Float)


class PlanRecommendations(Base):
    __tablename__ = 'plan_recommendations'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    plan_id = Column(BigInteger, ForeignKey('plan.id'), nullable=False)
    recommendation_id = Column(BigInteger, ForeignKey('recommendation.id'), nullable=False)


class Scenario(Base):
    __tablename__ = 'scenario'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String, nullable=False)
    created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
    budget = Column(Float)
    portfolio_id = Column(BigInteger, ForeignKey(Portfolio.id), nullable=False)
    housing_type = Column(String, nullable=False)
    goal = Column(String, nullable=False)
    goal_value = Column(String, nullable=False)
    trigger_file_path = Column(String, nullable=False)
    already_installed_file_path = Column(String)
    patches_file_path = Column(String)
    non_invasive_recommendations_file_path = Column(String)
    exclusions = Column(String)
    multi_plan = Column(Boolean, default=False)
    is_default = Column(Boolean, default=False, nullable=False)

    # Add in the fields we need, which were previously sitting at the portfolio level
    cost = Column(Float)
    contingency = Column(Float)
    funding = Column(Float)
    total_work_hours = Column(Float)
    energy_savings = Column(Float)
    co2_equivalent_savings = Column(Float)
    energy_cost_savings = Column(Float)
    epc_breakdown_pre_retrofit = Column(String)
    epc_breakdown_post_retrofit = Column(String)
    number_of_properties = Column(BigInteger)
    n_units_to_retrofit = Column(BigInteger)
    co2_per_unit_pre_retrofit = Column(String)
    co2_per_unit_post_retrofit = Column(String)
    energy_bill_per_unit_pre_retrofit = Column(String)
    energy_bill_per_unit_post_retrofit = Column(String)
    energy_consumption_per_unit_pre_retrofit = Column(String)
    energy_consumption_per_unit_post_retrofit = Column(String)
    valuation_improvement_per_unit = Column(String)
    cost_per_unit = Column(String)
    cost_per_co2_saved = Column(String)
    cost_per_sap_point = Column(String)
    valuation_return_on_investment = Column(String)
    property_valuation_increase = Column(Float)
    labour_days = Column(Float)
