-- Пересчёт ekb_districts.median_price_per_m2 + mean_price_per_m2 из rosreestr_deals.
--
-- Зачем: для половины районов ЕКБ были NULL (импорт Антона из SQLite не покрыл),
-- из-за чего recommend_mix давал district_factor=1.0 без учёта района и
-- cadastre_vs_market_pct = NULL (нет district_median для сравнения с кадастром).
-- Старые значения для Октябрьского/Орджоникидзевского (191K/205K) выглядят как
-- yandex/domrf-листинг, не реальные сделки — перезаписываем для консистентности.
--
-- Исключаем 'не определён' (служебная категория, не настоящий район).
--
-- Идемпотентно — можно перезапускать. Окно 24 мес даёт устойчивые медианы.
-- Если в районе <50 сделок за 24 мес — оставляем NULL (warning в recommend_mix).

CREATE OR REPLACE FUNCTION refresh_ekb_districts_median(window_months int DEFAULT 24, min_deals int DEFAULT 50)
RETURNS TABLE(district_name text, deals_used bigint, median_pm numeric, mean_pm numeric)
LANGUAGE plpgsql AS $$
BEGIN
    RETURN QUERY
    WITH per_district AS (
        SELECT d.district_name,
               COUNT(*)::bigint AS deals,
               PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY rd.price_per_sqm)::numeric AS p_median,
               AVG(rd.price_per_sqm)::numeric AS p_mean
          FROM rosreestr_deals rd
          JOIN cad_quarters_geom cq ON cq.cad_number = rd.quarter_cad_number
          JOIN ekb_districts_geom d ON ST_Intersects(d.geom, cq.geom)
         WHERE rd.region_code = 66
           AND rd.doc_type = 'ДДУ'
           AND rd.realestate_type_code = '002001003000'
           AND rd.area BETWEEN 15 AND 200
           AND rd.price_per_sqm BETWEEN 30000 AND 1000000
           AND rd.period_start_date >= NOW() - (window_months || ' months')::interval
         GROUP BY d.district_name
    ),
    upd AS (
        UPDATE ekb_districts e
           SET median_price_per_m2 = ROUND(pd.p_median, 0),
               mean_price_per_m2   = ROUND(pd.p_mean, 0)
          FROM per_district pd
         WHERE e.district_name = pd.district_name
           AND e.district_name <> 'не определён'
           AND pd.deals >= min_deals
        RETURNING e.district_name, pd.deals, pd.p_median, pd.p_mean
    )
    SELECT u.district_name::text, u.deals, ROUND(u.p_median, 0), ROUND(u.p_mean, 0)
      FROM upd u
     ORDER BY u.district_name;
END;
$$;

COMMENT ON FUNCTION refresh_ekb_districts_median(int, int) IS
    'Refresh ekb_districts.median_price_per_m2 + mean_price_per_m2 из ДДУ-сделок rosreestr_deals '
    'через spatial-join cad_quarters_geom + ekb_districts_geom. Окно по умолчанию 24 мес, '
    'минимум 50 сделок на район. Запускается Celery beat раз в месяц.';
