-- audit_address_sample.sql
-- Stratified sample of EKB houses for the address-mismatch audit (issue #582).
--
-- Strategy:
--   1. Spatial-join houses → gendesign_ekb_districts_geom via ST_Contains
--      (only houses with lat/lon falling inside one of the 8 admin polygons).
--   2. Partition by district, ROW_NUMBER() with a deterministic ORDER BY id
--      so repeated runs return the same sample (deterministic = matches the
--      "resumable per (house_id, audit_batch)" guarantee in 066 migration).
--   3. Keep top :limit_per_district per district → ~200 rows total for 8
--      districts × 25.
--
-- Bind param:
--   :limit_per_district — default 25, expressed as :limit_per_district
--     (psql variables resolve in :name form for the report; for Python use
--     SQLAlchemy text() with bindparams).
--
-- Columns returned:
--   id, address, lat, lon, district
--
-- NB: uses CAST(:x AS int) per project sql.md rule (psycopg v3 ignores ::type
-- after bind params).

WITH houses_in_districts AS (
    SELECT
        h.id,
        h.address,
        h.lat,
        h.lon,
        d.district_name AS district,
        h.geom
    FROM houses h
    JOIN gendesign_ekb_districts_geom d
      ON ST_Contains(d.geom, h.geom)
    WHERE h.lat IS NOT NULL
      AND h.lon IS NOT NULL
      AND h.address IS NOT NULL
      AND length(trim(h.address)) > 0
),
ranked AS (
    SELECT
        id,
        address,
        lat,
        lon,
        district,
        ROW_NUMBER() OVER (PARTITION BY district ORDER BY id) AS rn
    FROM houses_in_districts
)
SELECT id, address, lat, lon, district
FROM ranked
WHERE rn <= CAST(:limit_per_district AS int)
ORDER BY district, id;
