"""Generative Design — Stage 1c: ТЭП (technical-economic indicators).

From the Stage 1b placement (rectangular section footprints + floor count) we derive
the ``TEAP`` contract block with *real* numbers:

* ``built_area_sqm``        — пятно застройки (сумма площадей footprint-ов).
* ``total_floor_area_sqm``  — общая поэтажная площадь (GFA) = пятно * этажность.
* ``residential_area_sqm``  — продаваемая жилая = GFA * коэффициент эффективности
  (вычет МОП/лестниц/тех.помещений; зависит от класса жилья).
* ``apartments_count``      — жилая / средняя площадь квартиры (зависит от класса).
* ``density``               — плотность застройки = FAR = GFA / площадь участка.
* ``parking_spaces``        — машиноместа по упрощённой норме (мест на квартиру).

Все коэффициенты — упрощённые нормативные proxy для MVP (см. константы ниже).
Детерминированно, без LLM / внешних API / БД.
"""

from __future__ import annotations

import logging
import math
from typing import Literal

from shapely.geometry import Polygon

from app.schemas.concept import TEAP

logger = logging.getLogger(__name__)

HousingClass = Literal["econom", "comfort", "business"]

# ── Коэффициент эффективности площади (residential / GFA), доля ────────────────
# Доля продаваемой жилой в общей поэтажной (остальное — МОП, лестницы, тех.этаж).
# Бизнес-класс «тратит» больше на МОП/лобби -> ниже эффективность.
_EFFICIENCY_BY_CLASS: dict[HousingClass, float] = {
    "econom": 0.82,
    "comfort": 0.78,
    "business": 0.72,
}

# ── Средняя площадь квартиры (кв.м) по классу — выше класс -> крупнее лот ──────
_AVG_APARTMENT_SQM: dict[HousingClass, float] = {
    "econom": 42.0,
    "comfort": 55.0,
    "business": 78.0,
}

# ── Норма парковки (машиномест на квартиру) по классу ─────────────────────────
_PARKING_PER_APARTMENT: dict[HousingClass, float] = {
    "econom": 0.8,
    "comfort": 1.0,
    "business": 1.5,
}


def compute_teap(
    *,
    footprints: list[Polygon],
    floors: int,
    site_area_sqm: float,
    housing_class: HousingClass,
) -> TEAP:
    """Свести footprints + этажность в :class:`TEAP`.

    Args:
        footprints: метрические пятна секций (кв.м берётся из ``.area``).
        floors: этажность (общая для всех секций варианта).
        site_area_sqm: площадь участка для плотности (FAR).
        housing_class: класс жилья — задаёт эффективность/средний лот/парковку.
    """
    built_area = float(sum(fp.area for fp in footprints))
    total_floor_area = built_area * max(0, floors)

    efficiency = _EFFICIENCY_BY_CLASS[housing_class]
    residential_area = total_floor_area * efficiency

    avg_apartment = _AVG_APARTMENT_SQM[housing_class]
    apartments_count = math.floor(residential_area / avg_apartment) if avg_apartment else 0

    # Плотность застройки = FAR (GFA / площадь участка). Защита от деления на ноль.
    density = total_floor_area / site_area_sqm if site_area_sqm > 0 else 0.0

    parking_norm = _PARKING_PER_APARTMENT[housing_class]
    parking_spaces = math.ceil(apartments_count * parking_norm)

    teap = TEAP(
        built_area_sqm=round(built_area, 1),
        total_floor_area_sqm=round(total_floor_area, 1),
        residential_area_sqm=round(residential_area, 1),
        apartments_count=apartments_count,
        density=round(density, 3),
        parking_spaces=parking_spaces,
    )
    logger.info(
        "TEAP: built=%.0f GFA=%.0f resid=%.0f apts=%d FAR=%.2f parking=%d",
        teap.built_area_sqm,
        teap.total_floor_area_sqm,
        teap.residential_area_sqm,
        teap.apartments_count,
        teap.density,
        teap.parking_spaces,
    )
    return teap


__all__ = ["HousingClass", "compute_teap"]
