-- Загрузка DDS fact_flight_sales: инкрементальный UPSERT по (ticket_no, flight_id).

-- Statement 1: UPDATE существующих строк факта.
-- Обновляем только мутабельные поля; SK измерений не перезаписываем.
UPDATE dds.fact_flight_sales AS f
SET seat_no    = bp.seat_no,
    price      = seg.amount,
    is_boarded = (bp.ticket_no IS NOT NULL),
    _load_id   = '{{ run_id }}',
    _load_ts   = now()
FROM ods.segments AS seg
LEFT JOIN ods.boarding_passes AS bp
    ON bp.ticket_no = seg.ticket_no
    AND bp.flight_id = seg.flight_id
WHERE f.ticket_no = seg.ticket_no
    AND f.flight_id = seg.flight_id
    AND (
        f.is_boarded IS DISTINCT FROM (bp.ticket_no IS NOT NULL)
        OR f.price IS DISTINCT FROM seg.amount
        OR f.seat_no IS DISTINCT FROM bp.seat_no
    );

-- Statement 2: INSERT новых строк факта.
-- Dimension SK фиксируются на момент вставки (point-in-time для SCD2 routes).
WITH fact_src AS (
    SELECT
        seg.ticket_no,
        seg.flight_id,
        cal.calendar_sk,
        dep.airport_sk AS departure_airport_sk,
        arr.airport_sk AS arrival_airport_sk,
        ap.airplane_sk,
        tar.tariff_sk,
        pax.passenger_sk,
        rte.route_sk,
        tkt.book_ref,
        bkg.book_date::DATE AS book_date,
        bp.seat_no,
        seg.amount AS price,
        (bp.ticket_no IS NOT NULL) AS is_boarded
    FROM ods.segments AS seg
    JOIN ods.tickets AS tkt
        ON tkt.ticket_no = seg.ticket_no
    JOIN ods.bookings AS bkg
        ON bkg.book_ref = tkt.book_ref
    JOIN ods.flights AS flt
        ON flt.flight_id = seg.flight_id
    -- Учебный комментарий: Late-arriving dimensions (Опаздывающие измерения)
    -- Мы используем LEFT JOIN, так как факт (рейс/билет) может прийти раньше,
    -- чем справочник (пассажир/маршрут) обновится в DDS.
    LEFT JOIN dds.dim_routes AS rte
        ON rte.route_bk = flt.route_no
        AND flt.scheduled_departure::DATE >= rte.valid_from
        AND (rte.valid_to IS NULL OR flt.scheduled_departure::DATE < rte.valid_to)
    LEFT JOIN dds.dim_calendar AS cal
        ON cal.date_actual = flt.scheduled_departure::DATE
    LEFT JOIN dds.dim_airports AS dep
        ON dep.airport_bk = rte.departure_airport
    LEFT JOIN dds.dim_airports AS arr
        ON arr.airport_bk = rte.arrival_airport
    LEFT JOIN dds.dim_airplanes AS ap
        ON ap.airplane_bk = rte.airplane_code
    LEFT JOIN dds.dim_tariffs AS tar
        ON tar.fare_conditions = seg.fare_conditions
    LEFT JOIN dds.dim_passengers AS pax
        ON pax.passenger_id = tkt.passenger_id
    LEFT JOIN ods.boarding_passes AS bp
        ON bp.ticket_no = seg.ticket_no
        AND bp.flight_id = seg.flight_id
)
INSERT INTO dds.fact_flight_sales (
    calendar_sk,
    departure_airport_sk,
    arrival_airport_sk,
    airplane_sk,
    tariff_sk,
    passenger_sk,
    route_sk,
    book_ref,
    ticket_no,
    flight_id,
    book_date,
    seat_no,
    price,
    is_boarded,
    _load_id,
    _load_ts
)
SELECT
    s.calendar_sk,
    s.departure_airport_sk,
    s.arrival_airport_sk,
    s.airplane_sk,
    s.tariff_sk,
    s.passenger_sk,
    s.route_sk,
    s.book_ref,
    s.ticket_no,
    s.flight_id,
    s.book_date,
    s.seat_no,
    s.price,
    s.is_boarded,
    '{{ run_id }}',
    now()
FROM fact_src AS s
WHERE NOT EXISTS (
    SELECT 1
    FROM dds.fact_flight_sales AS f
    WHERE f.ticket_no = s.ticket_no
        AND f.flight_id = s.flight_id
);

ANALYZE dds.fact_flight_sales;
