-- Загрузка DDS dim_passengers: SCD1 UPSERT (UPDATE изменившихся + INSERT новых).

-- Учебный комментарий: Используем TEMP TABLE для подготовки дельты.
-- Это избавляет от дублирования сложной оконной функции в UPDATE и INSERT блоках.
CREATE TEMP TABLE tmp_passengers_src ON COMMIT DROP AS
SELECT
    d.passenger_id,
    d.passenger_name
FROM (
    SELECT
        t.passenger_id,
        t.passenger_name,
        ROW_NUMBER() OVER (
            PARTITION BY t.passenger_id
            ORDER BY t.event_ts DESC NULLS LAST, t._load_ts DESC, t.ticket_no DESC
        ) AS rn
    FROM ods.tickets AS t
    WHERE t.passenger_id IS NOT NULL
        AND t.passenger_id <> ''
        AND t.passenger_name IS NOT NULL
        AND t.passenger_name <> ''
) AS d
WHERE d.rn = 1;

-- Statement 1: UPDATE существующих записей (если атрибуты изменились).
UPDATE dds.dim_passengers AS d
SET passenger_name = s.passenger_name,
    updated_at     = now(),
    _load_id       = '{{ run_id }}',
    _load_ts       = now()
FROM tmp_passengers_src AS s
WHERE d.passenger_id = s.passenger_id
    AND d.passenger_name IS DISTINCT FROM s.passenger_name;

-- Statement 2: INSERT новых записей (MAX(sk) + ROW_NUMBER()).
WITH max_sk AS (
    -- Учебный комментарий: Генерация SK через MAX() + ROW_NUMBER()
    -- Этот подход работает безопасно только потому, что Airflow запускает
    -- джобы загрузки для одной таблицы строго последовательно (concurrency=1).
    SELECT COALESCE(MAX(passenger_sk), 0) AS v
    FROM dds.dim_passengers
)
INSERT INTO dds.dim_passengers (
    passenger_sk,
    passenger_id,
    passenger_name,
    created_at,
    updated_at,
    _load_id,
    _load_ts
)
SELECT
    (SELECT v FROM max_sk) + ROW_NUMBER() OVER (ORDER BY s.passenger_id)::INTEGER,
    s.passenger_id,
    s.passenger_name,
    now(),
    now(),
    '{{ run_id }}',
    now()
FROM tmp_passengers_src AS s
WHERE NOT EXISTS (
    SELECT 1
    FROM dds.dim_passengers AS d
    WHERE d.passenger_id = s.passenger_id
);

ANALYZE dds.dim_passengers;
