"""Buildings — страница «доля квартир дома в продаже» (мигр. 143).

Дома вторичного рынка, где active_secondary / flat_count_effective >= threshold%.
Данные берём из готового view v_building_sale_share (логику доли не пересчитываем).

Endpoints:
  - GET /api/v1/buildings/sale-share            — список домов
  - GET /api/v1/buildings/{house_id}/listings   — активные вторичные объявления дома
  - GET /api/v1/buildings/sale-share/summary     — сводка для слайдера % + coverage
"""

from __future__ import annotations

import logging
from typing import Annotated

from fastapi import APIRouter, Depends, Path, Query
from sqlalchemy import text
from sqlalchemy.orm import Session

from app.core.db import get_db
from app.schemas.buildings import (
    BuildingListing,
    BuildingSaleShare,
    HistogramBucket,
    SaleShareSummary,
)
from app.services.buildings_query import (
    HISTOGRAM_BUCKETS,
    build_listings_query,
    build_sale_share_query,
    build_summary_histogram_query,
    build_summary_scalars_query,
)

logger = logging.getLogger(__name__)

router = APIRouter()


@router.get("/sale-share", response_model=list[BuildingSaleShare])
async def list_sale_share(
    db: Annotated[Session, Depends(get_db)],
    min_pct: Annotated[float, Query(ge=0, le=1000)] = 5.0,
    max_pct: Annotated[float | None, Query(ge=0, le=1000)] = None,
    city: Annotated[str | None, Query(max_length=120)] = None,
    price_min: Annotated[int | None, Query(ge=0)] = None,
    price_max: Annotated[int | None, Query(ge=0)] = None,
    year_min: Annotated[int | None, Query(ge=1800, le=2100)] = None,
    year_max: Annotated[int | None, Query(ge=1800, le=2100)] = None,
    house_type: Annotated[str | None, Query(max_length=40)] = None,
    sort: Annotated[
        str,
        Query(
            pattern="^(share_desc|share_45d_desc|active_desc|count_45d_desc"
            "|exposure_desc|price_asc|price_desc)$"
        ),
    ] = "share_desc",
    limit: Annotated[int, Query(ge=1, le=1000)] = 200,
) -> list[BuildingSaleShare]:
    """Дома вторички, где ЛЮБОЙ из двух % (now / 45д) >= min_pct (+ фильтры)."""
    sql, args = build_sale_share_query(
        min_pct=min_pct,
        max_pct=max_pct,
        city=city,
        price_min=price_min,
        price_max=price_max,
        year_min=year_min,
        year_max=year_max,
        house_type=house_type,
        sort=sort,
        limit=limit,
    )
    rows = db.execute(text(sql), args).mappings().all()
    return [BuildingSaleShare.model_validate(r) for r in rows]


@router.get("/{house_id}/listings", response_model=list[BuildingListing])
async def list_building_listings(
    db: Annotated[Session, Depends(get_db)],
    house_id: Annotated[int, Path(ge=1)],
) -> list[BuildingListing]:
    """Активные вторичные объявления в одном доме (для drawer), ORDER BY price."""
    sql, args = build_listings_query(house_id)
    rows = db.execute(text(sql), args).mappings().all()
    return [BuildingListing.model_validate(r) for r in rows]


@router.get("/sale-share/summary", response_model=SaleShareSummary)
async def sale_share_summary(
    db: Annotated[Session, Depends(get_db)],
) -> SaleShareSummary:
    """Сводка распределения обоих % (now + 45д): coverage, max, p95, две гистограммы."""
    scalars = db.execute(text(build_summary_scalars_query())).mappings().one()

    def _histogram(column: str) -> list[HistogramBucket]:
        rows = db.execute(text(build_summary_histogram_query(column))).mappings().all()
        counts = {str(r["bucket"]): int(r["count"]) for r in rows}
        return [HistogramBucket(bucket=b, count=counts.get(b, 0)) for b in HISTOGRAM_BUCKETS]

    def _opt_float(key: str) -> float | None:
        return float(scalars[key]) if scalars[key] is not None else None

    return SaleShareSummary(
        total_secondary_buildings=int(scalars["total_secondary_buildings"]),
        buildings_with_denominator=int(scalars["buildings_with_denominator"]),
        coverage_pct=float(scalars["coverage_pct"]),
        max_pct=_opt_float("max_pct"),
        p95_pct=_opt_float("p95_pct"),
        max_pct_45d=_opt_float("max_pct_45d"),
        p95_pct_45d=_opt_float("p95_pct_45d"),
        histogram=_histogram("sale_share_pct"),
        histogram_45d=_histogram("sale_share_pct_45d"),
    )
