-- GeoNames global city/municipality population (cities1000 bulk dataset, pop ≥ 1K).
-- Global fallback for countries not covered by Eurostat, Census, or ONS.
-- Broad coverage (140K+ locations) enables Gemeinde-level market intelligence.
-- One row per geoname_id (GeoNames stable numeric identifier).
--
-- Source: data/landing/geonames/{year}/{month}/cities_global.jsonl.gz

MODEL (
  name staging.stg_population_geonames,
  kind FULL,
  cron '@daily',
  grain geoname_id
);

SELECT
  TRY_CAST(geoname_id  AS INTEGER)  AS geoname_id,
  TRIM(city_name)                   AS city_name,
  UPPER(country_code)               AS country_code,
  TRY_CAST(lat         AS DOUBLE)   AS lat,
  TRY_CAST(lon         AS DOUBLE)   AS lon,
  NULLIF(TRIM(admin1_code), '')     AS admin1_code,
  NULLIF(TRIM(admin2_code), '')     AS admin2_code,
  TRY_CAST(population  AS BIGINT)   AS population,
  TRY_CAST(ref_year    AS INTEGER)  AS ref_year,
  CURRENT_DATE                      AS extracted_date
FROM read_json(
  @LANDING_DIR || '/geonames/*/*/cities_global.jsonl.gz',
  format = 'newline_delimited',
  columns = {
    geoname_id: 'INTEGER', city_name: 'VARCHAR', country_code: 'VARCHAR',
    lat: 'DOUBLE', lon: 'DOUBLE', admin1_code: 'VARCHAR', admin2_code: 'VARCHAR',
    population: 'BIGINT', ref_year: 'INTEGER'
  }
)
WHERE geoname_id IS NOT NULL
  AND population IS NOT NULL
  AND population > 0
  AND city_name IS NOT NULL
  AND lat IS NOT NULL
  AND lon IS NOT NULL
  -- Reject names with non-Latin characters (CJK, Cyrillic, Arabic, Thai, etc.)
  -- Allows ASCII + Latin Extended (diacritics: ÄÖÜ, àéî, ñ, ø, etc.)
  AND regexp_matches(city_name, '^[\x20-\x7E\u00C0-\u024F\u1E00-\u1EFF]+$')
