from sqlalchemy import func
from backend.app.db.models.recommendations import Plan, PlanRecommendations, Recommendation
from backend.app.db.models.portfolio import Portfolio


def aggregate_portfolio_recommendations(
    session, portfolio_id: int, total_valuation_increase: float, labour_days: float, aggregated_data: dict
):
    # Aggregate multiple fields
    aggregates = (
        session.query(
            func.sum(Recommendation.estimated_cost).label("cost"),
            func.sum(Recommendation.total_work_hours).label("total_work_hours"),
            func.sum(Recommendation.adjusted_heat_demand).label("energy_savings"),
            func.sum(Recommendation.co2_equivalent_savings).label("co2_equivalent_savings"),
            func.sum(Recommendation.energy_cost_savings).label("energy_cost_savings"),
        )
        .join(PlanRecommendations, PlanRecommendations.recommendation_id == Recommendation.id)
        .join(Plan, Plan.id == PlanRecommendations.plan_id)
        .filter(Plan.portfolio_id == portfolio_id, Plan.is_default == True, Recommendation.default == True)
        .one()
    )

    aggregates_dict = {
        "cost": aggregates.cost or 0,
        "total_work_hours": aggregates.total_work_hours or 0,
        "energy_savings": aggregates.energy_savings or 0,
        "co2_equivalent_savings": aggregates.co2_equivalent_savings or 0,
        "energy_cost_savings": aggregates.energy_cost_savings or 0,
        **aggregated_data
    }

    # Get the portfolio and update the fields
    portfolio = session.query(Portfolio).filter_by(id=portfolio_id).one()
    # Update the data
    for key, value in aggregates_dict.items():
        setattr(portfolio, key, value)

    # Insert total valuation increase and labour days
    portfolio.property_valuation_increase = total_valuation_increase
    portfolio.labour_days = labour_days

    # Merge the updated portfolio back into the session
    session.merge(portfolio)
    session.flush()
