"""Layout signature extraction для Issue #113 (Phase 2.1 minimal).

Без `layout_type` / `balcony_count` — ждут B2B Объектив (#52).
"""

from __future__ import annotations

from typing import Literal

RoomBucket = Literal["studio", "euro-1", "euro-2", "1", "2", "3", "4+"]
AreaBin = Literal["<25", "25-40", "40-60", "60-80", "80-100", "100+"]


def room_bucket_from_flat(
    rooms: int | None,
    flat_type: str | None,
    is_studio: bool | None,
    total_area: float | None = None,
) -> RoomBucket:
    """Determine room_bucket из kn_flats полей.

    Priority:
    1. is_studio=True OR flat_type='Квартира-студия' → "studio"
    2. rooms=0 (без is_studio) → "studio"
    3. Fix SF-08: rooms=2 + area<35 → "euro-1" (DOM.РФ маркирует малогабаритные как 2-комн)
    4. Fix SF-08: rooms=2 + area<50 → "euro-2" (евро-двушки 35-50м²)
    5. rooms IN (1, 2, 3) → str(rooms)
    6. rooms >= 4 → "4+"
    7. fallback на "1" (rooms is None и не studio)
    """
    if is_studio is True or flat_type == "Квартира-студия":
        return "studio"
    if rooms is None:
        return "1"
    if rooms == 0:
        return "studio"
    if rooms == 2 and total_area is not None:
        if total_area < 35.0:
            return "euro-1"
        if total_area < 50.0:
            return "euro-2"
    if rooms >= 4:
        return "4+"
    if rooms in (1, 2, 3):
        return str(rooms)  # type: ignore[return-value]
    return "1"


def area_bin(area_m2: float) -> AreaBin:
    """Bucket площади per ARN-buckets (НСПД)."""
    if area_m2 < 25.0:
        return "<25"
    if area_m2 < 40.0:
        return "25-40"
    if area_m2 < 60.0:
        return "40-60"
    if area_m2 < 80.0:
        return "60-80"
    if area_m2 < 100.0:
        return "80-100"
    return "100+"


def layout_signature(room_bucket_val: RoomBucket, area_bin_val: AreaBin) -> str:
    """Deterministic string-signature для группировки."""
    return f"{room_bucket_val}__{area_bin_val}"
