-- Conformed country dimension — single authoritative source for all country metadata.
--
-- Consolidates data previously duplicated across dim_cities and dim_locations:
--   - country_name_en / country_slug  (was: ~50-line CASE blocks in both models)
--   - median_income_pps               (Eurostat PPS preferred, World Bank GNI PPP fallback)
--   - energy prices, labour costs, PLI indices  (Eurostat, WB price level ratio fallback)
--   - cost override columns for the financial calculator
--
-- World Bank fallback: for non-EU countries (AR, MX, AE, AU, etc.), income and PLI
-- are derived from WB WDI indicators calibrated to the Eurostat scale using Germany
-- as anchor. See de_calibration CTE. EU countries keep exact Eurostat values.
--
-- Used by: dim_cities, dim_locations, pseo_city_costs_de, planner_defaults.
-- Grain: country_code (one row per ISO 3166-1 alpha-2 country code).
-- Kind: FULL — small table (~40 rows), full refresh daily.
--
-- Cost override columns:
--   NULL = fall through to calculator.py DEFAULTS (safe: auto-mapping filters None).
--   For DE (the baseline country) all overrides are NULL to preserve exact DEFAULTS.
--   For countries missing Eurostat data, NULLs propagate naturally.
--   camelCase column aliases match DEFAULTS keys for auto-mapping in content/__init__.py.
--
-- !! DE baseline values sourced from calculator.py DEFAULTS (web/src/padelnomics/planner/calculator.py).
-- !! If DEFAULTS change, the hardcoded baseline values below must be updated to match.
-- !! Search "DE baseline" in this file to find all affected lines.

MODEL (
  name foundation.dim_countries,
  kind FULL,
  cron '@daily',
  grain country_code
);

WITH
-- Latest income per country
latest_income AS (
  SELECT country_code, median_income_pps, ref_year AS income_year
  FROM staging.stg_income
  QUALIFY ROW_NUMBER() OVER (PARTITION BY country_code ORDER BY ref_year DESC) = 1
),
-- Latest electricity price per country (use most recent semi-annual period)
latest_electricity AS (
  SELECT country_code, electricity_eur_kwh, ref_period
  FROM staging.stg_electricity_prices
  QUALIFY ROW_NUMBER() OVER (PARTITION BY country_code ORDER BY ref_period DESC) = 1
),
-- Latest gas price per country
latest_gas AS (
  SELECT country_code, gas_eur_gj, ref_period
  FROM staging.stg_gas_prices
  QUALIFY ROW_NUMBER() OVER (PARTITION BY country_code ORDER BY ref_period DESC) = 1
),
-- Latest labour cost per country
latest_labour AS (
  SELECT country_code, labour_cost_eur_hour, ref_year
  FROM staging.stg_labour_costs
  QUALIFY ROW_NUMBER() OVER (PARTITION BY country_code ORDER BY ref_year DESC) = 1
),
-- Latest PLI per (country, category)
latest_pli AS (
  SELECT country_code, category, pli, ref_year
  FROM staging.stg_price_levels
  QUALIFY ROW_NUMBER() OVER (PARTITION BY country_code, category ORDER BY ref_year DESC) = 1
),
-- Pivot PLI categories into columns per country
pli_pivoted AS (
  SELECT
    country_code,
    MAX(pli) FILTER (WHERE category = 'construction') AS construction,
    MAX(pli) FILTER (WHERE category = 'housing')      AS housing,
    MAX(pli) FILTER (WHERE category = 'services')     AS services,
    MAX(pli) FILTER (WHERE category = 'misc')         AS misc,
    MAX(pli) FILTER (WHERE category = 'government')   AS government
  FROM latest_pli
  GROUP BY country_code
),
-- DE baseline rows for ratio computation
-- NULL-safe: if DE is missing from a source, ratios produce NULL (safe fallthrough).
de_pli AS (
  SELECT construction, housing, services, misc, government
  FROM pli_pivoted WHERE country_code = 'DE'
),
de_elec AS (
  SELECT electricity_eur_kwh FROM latest_electricity WHERE country_code = 'DE'
),
de_gas AS (
  SELECT gas_eur_gj FROM latest_gas WHERE country_code = 'DE'
),
-- Latest World Bank WDI per country (GNI PPP + price level ratio)
latest_wb AS (
  SELECT country_code, gni_ppp, price_level_ratio, ref_year AS wb_year
  FROM staging.stg_worldbank_income
  WHERE gni_ppp IS NOT NULL OR price_level_ratio IS NOT NULL
  QUALIFY ROW_NUMBER() OVER (PARTITION BY country_code ORDER BY ref_year DESC) = 1
),
-- Germany calibration anchor: Eurostat PPS + WB GNI PPP + WB price ratio + Eurostat PLI construction.
-- Used to scale World Bank values into Eurostat-comparable ranges.
-- Single row; if DE is missing from any source, that ratio produces NULL (safe fallthrough).
de_calibration AS (
  SELECT
    i.median_income_pps   AS de_eurostat_pps,
    wb.gni_ppp            AS de_gni_ppp,
    wb.price_level_ratio  AS de_price_level_ratio,
    p.construction        AS de_pli_construction
  FROM (SELECT median_income_pps FROM latest_income WHERE country_code = 'DE') i
  CROSS JOIN (SELECT gni_ppp, price_level_ratio FROM latest_wb WHERE country_code = 'DE') wb
  CROSS JOIN (SELECT construction FROM pli_pivoted WHERE country_code = 'DE') p
),
-- All distinct country codes from any source
all_countries AS (
  SELECT country_code FROM latest_income
  UNION
  SELECT country_code FROM latest_electricity
  UNION
  SELECT country_code FROM latest_gas
  UNION
  SELECT country_code FROM latest_labour
  UNION
  SELECT country_code FROM pli_pivoted
  UNION
  SELECT country_code FROM latest_wb
  -- Ensure known padel markets appear even if Eurostat doesn't cover them yet
  UNION ALL
  SELECT unnest(['DE','ES','GB','FR','IT','PT','AT','CH','NL','BE','SE','NO','DK','FI',
                 'US','AR','MX','AE','AU','IE']) AS country_code
)
SELECT
  ac.country_code,
  -- Country name and slug (single definition, replacing duplicated CASE blocks)
  CASE ac.country_code
    WHEN 'DE' THEN 'Germany'
    WHEN 'ES' THEN 'Spain'
    WHEN 'GB' THEN 'United Kingdom'
    WHEN 'FR' THEN 'France'
    WHEN 'IT' THEN 'Italy'
    WHEN 'PT' THEN 'Portugal'
    WHEN 'AT' THEN 'Austria'
    WHEN 'CH' THEN 'Switzerland'
    WHEN 'NL' THEN 'Netherlands'
    WHEN 'BE' THEN 'Belgium'
    WHEN 'SE' THEN 'Sweden'
    WHEN 'NO' THEN 'Norway'
    WHEN 'DK' THEN 'Denmark'
    WHEN 'FI' THEN 'Finland'
    WHEN 'US' THEN 'United States'
    WHEN 'AR' THEN 'Argentina'
    WHEN 'MX' THEN 'Mexico'
    WHEN 'AE' THEN 'UAE'
    WHEN 'AU' THEN 'Australia'
    WHEN 'IE' THEN 'Ireland'
    ELSE ac.country_code
  END                                                            AS country_name_en,
  LOWER(REGEXP_REPLACE(
    CASE ac.country_code
      WHEN 'DE' THEN 'Germany'
      WHEN 'ES' THEN 'Spain'
      WHEN 'GB' THEN 'United Kingdom'
      WHEN 'FR' THEN 'France'
      WHEN 'IT' THEN 'Italy'
      WHEN 'PT' THEN 'Portugal'
      WHEN 'AT' THEN 'Austria'
      WHEN 'CH' THEN 'Switzerland'
      WHEN 'NL' THEN 'Netherlands'
      WHEN 'BE' THEN 'Belgium'
      WHEN 'SE' THEN 'Sweden'
      WHEN 'NO' THEN 'Norway'
      WHEN 'DK' THEN 'Denmark'
      WHEN 'FI' THEN 'Finland'
      WHEN 'US' THEN 'United States'
      WHEN 'AR' THEN 'Argentina'
      WHEN 'MX' THEN 'Mexico'
      WHEN 'AE' THEN 'UAE'
      WHEN 'AU' THEN 'Australia'
      WHEN 'IE' THEN 'Ireland'
      ELSE ac.country_code
    END, '[^a-zA-Z0-9]+', '-'
  ))                                                             AS country_slug,
  -- Income: Eurostat PPS preferred, World Bank GNI PPP scaled to PPS as fallback
  COALESCE(
    i.median_income_pps,
    ROUND(wb.gni_ppp * (de_cal.de_eurostat_pps / NULLIF(de_cal.de_gni_ppp, 0)), 0)
  )                                                            AS median_income_pps,
  COALESCE(i.income_year, wb.wb_year)                          AS income_year,
  -- Raw energy and labour data (for reference / future staffed-scenario use)
  e.electricity_eur_kwh,
  g.gas_eur_gj,
  la.labour_cost_eur_hour,
  -- PLI construction: Eurostat preferred, World Bank price level ratio scaled to PLI as fallback
  COALESCE(
    p.construction,
    ROUND(wb.price_level_ratio / NULLIF(de_cal.de_price_level_ratio, 0) * de_cal.de_pli_construction, 1)
  )                                                              AS pli_construction,
  p.housing                                                      AS pli_housing,
  p.services                                                     AS pli_services,
  p.misc                                                         AS pli_misc,
  p.government                                                   AS pli_government,
  -- ── Calculator cost override columns ────────────────────────────────────
  -- NULL for DE = fall through to calculator.py DEFAULTS (safe: auto-mapping skips None).
  -- Formulas: country_value = DE_default × (country_price / DE_price)
  --                        or DE_default × (country_PLI / DE_PLI)
  --
  -- OPEX overrides — energy (direct price ratio)
  -- DE baseline: electricity=600, heating=400 (see calculator.py DEFAULTS)
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(600.0 * (e.electricity_eur_kwh / de_e.electricity_eur_kwh), 0)
  END                                                            AS electricity,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(400.0 * (g.gas_eur_gj / de_g.gas_eur_gj), 0)
  END                                                            AS heating,
  -- OPEX overrides — PLI-scaled (housing category)
  -- DE baseline: rentSqm=4, water=125, outdoorRent=400
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(4.0 * (p.housing / de_p.housing), 2)
  END                                                            AS rent_sqm,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(125.0 * (p.housing / de_p.housing), 0)
  END                                                            AS water,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(400.0 * (p.housing / de_p.housing), 0)
  END                                                            AS outdoor_rent,
  -- OPEX overrides — PLI-scaled (misc category)
  -- DE baseline: insurance=300
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(300.0 * (p.misc / de_p.misc), 0)
  END                                                            AS insurance,
  -- OPEX overrides — PLI-scaled (services category)
  -- DE baseline: cleaning=300, maintenance=300, marketing=350
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(300.0 * (p.services / de_p.services), 0)
  END                                                            AS cleaning,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(300.0 * (p.services / de_p.services), 0)
  END                                                            AS maintenance,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(350.0 * (p.services / de_p.services), 0)
  END                                                            AS marketing,
  -- OPEX overrides — PLI-scaled (government category)
  -- DE baseline: propertyTax=250, permitsCompliance=12000
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(250.0 * (p.government / de_p.government), 0)
  END                                                            AS property_tax,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(12000.0 * (p.government / de_p.government), 0)
  END                                                            AS permits_compliance,
  -- CAPEX overrides — PLI-scaled (construction category)
  -- DE baseline: hallCostSqm=500, foundationSqm=150, hvac=100000, electrical=60000,
  --              sanitary=80000, parking=50000, fitout=40000, planning=100000,
  --              fireProtection=80000, floorPrep=12000, hvacUpgrade=20000,
  --              lightingUpgrade=10000, outdoorFoundation=35, outdoorSiteWork=8000,
  --              outdoorLighting=4000, outdoorFencing=6000, workingCapital=15000
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(500.0 * (p.construction / de_p.construction), 0)
  END                                                            AS hall_cost_sqm,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(150.0 * (p.construction / de_p.construction), 0)
  END                                                            AS foundation_sqm,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(100000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS hvac,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(60000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS electrical,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(80000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS sanitary,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(50000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS parking,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(40000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS fitout,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(100000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS planning,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(80000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS fire_protection,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(12000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS floor_prep,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(20000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS hvac_upgrade,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(10000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS lighting_upgrade,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(35.0 * (p.construction / de_p.construction), 0)
  END                                                            AS outdoor_foundation,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(8000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS outdoor_site_work,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(4000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS outdoor_lighting,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(6000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS outdoor_fencing,
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(15000.0 * (p.construction / de_p.construction), 0)
  END                                                            AS working_capital,
  -- CAPEX overrides — PLI-scaled (housing category)
  -- DE baseline: landPriceSqm=60
  CASE WHEN ac.country_code = 'DE' THEN NULL
       ELSE ROUND(60.0 * (p.housing / de_p.housing), 0)
  END                                                            AS land_price_sqm
FROM (SELECT DISTINCT country_code FROM all_countries WHERE LENGTH(country_code) = 2) ac
LEFT JOIN latest_income i       ON ac.country_code = i.country_code
LEFT JOIN latest_electricity e  ON ac.country_code = e.country_code
LEFT JOIN latest_gas g          ON ac.country_code = g.country_code
LEFT JOIN latest_labour la      ON ac.country_code = la.country_code
LEFT JOIN pli_pivoted p         ON ac.country_code = p.country_code
LEFT JOIN latest_wb wb         ON ac.country_code = wb.country_code
CROSS JOIN de_pli de_p
CROSS JOIN de_elec de_e
CROSS JOIN de_gas de_g
CROSS JOIN de_calibration de_cal
-- Enforce grain
QUALIFY ROW_NUMBER() OVER (PARTITION BY ac.country_code ORDER BY ac.country_code) = 1
