-- ============================================================
-- Phase 2 Step 2: Track tables + fr24_mart schema
-- ============================================================

-- ── fr24_ext: FR24 API tracks ────────────────────────────────

CREATE TABLE IF NOT EXISTS fr24_ext.flight_tracks_fr24 (
    id               BIGSERIAL PRIMARY KEY,
    fr24_id          VARCHAR(20) NOT NULL UNIQUE,
    flight_number    VARCHAR(20),
    callsign         VARCHAR(20),
    aircraft_type    VARCHAR(10),
    registration     VARCHAR(15),
    origin_icao      VARCHAR(5),
    destination_icao VARCHAR(5),
    actual_takeoff   TIMESTAMPTZ,
    actual_landed    TIMESTAMPTZ,
    flight_date      DATE NOT NULL,
    fetched_at       TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_flight_tracks_fr24_date ON fr24_ext.flight_tracks_fr24 (flight_date);
CREATE INDEX IF NOT EXISTS idx_flight_tracks_fr24_flight ON fr24_ext.flight_tracks_fr24 (flight_number, flight_date);

CREATE TABLE IF NOT EXISTS fr24_ext.track_points_fr24 (
    id          BIGSERIAL PRIMARY KEY,
    track_id    BIGINT NOT NULL REFERENCES fr24_ext.flight_tracks_fr24(id) ON DELETE CASCADE,
    observed_at TIMESTAMPTZ NOT NULL,
    lat         DOUBLE PRECISION NOT NULL,
    lon         DOUBLE PRECISION NOT NULL,
    altitude_ft INTEGER,
    gspeed_kt   INTEGER,
    vspeed_fpm  INTEGER,
    heading     SMALLINT,
    squawk      VARCHAR(5),
    source      VARCHAR(10)
);
CREATE INDEX IF NOT EXISTS idx_track_points_fr24_track ON fr24_ext.track_points_fr24 (track_id, observed_at);

-- ── fr24_ext: FlightAware tracks ─────────────────────────────

CREATE TABLE IF NOT EXISTS fr24_ext.flight_tracks_fa (
    id               BIGSERIAL PRIMARY KEY,
    fa_flight_id     VARCHAR(50) NOT NULL UNIQUE,
    ident_iata       VARCHAR(10),
    ident_icao       VARCHAR(10),
    registration     VARCHAR(15),
    aircraft_type    VARCHAR(10),
    origin_icao      VARCHAR(20),
    destination_icao VARCHAR(20),
    actual_off       TIMESTAMPTZ,
    actual_on        TIMESTAMPTZ,
    departure_delay  INTEGER,   -- seconds
    arrival_delay    INTEGER,   -- seconds
    actual_distance  INTEGER,   -- nautical miles
    flight_date      DATE NOT NULL,
    fetched_at       TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_flight_tracks_fa_date ON fr24_ext.flight_tracks_fa (flight_date);
CREATE INDEX IF NOT EXISTS idx_flight_tracks_fa_ident ON fr24_ext.flight_tracks_fa (ident_iata, flight_date);

CREATE TABLE IF NOT EXISTS fr24_ext.track_points_fa (
    id          BIGSERIAL PRIMARY KEY,
    track_id    BIGINT NOT NULL REFERENCES fr24_ext.flight_tracks_fa(id) ON DELETE CASCADE,
    observed_at TIMESTAMPTZ NOT NULL,
    lat         DOUBLE PRECISION NOT NULL,
    lon         DOUBLE PRECISION NOT NULL,
    altitude_ft INTEGER,   -- already converted: hundreds_of_feet * 100
    gspeed_kt   INTEGER,
    heading     SMALLINT,
    update_type VARCHAR(5) -- M=ADS-B, D=dead reckoning
);
CREATE INDEX IF NOT EXISTS idx_track_points_fa_track ON fr24_ext.track_points_fa (track_id, observed_at);

-- ── fr24_mart schema ─────────────────────────────────────────

CREATE SCHEMA IF NOT EXISTS fr24_mart;

-- Unified flights table
CREATE TABLE IF NOT EXISTS fr24_mart.flights (
    id               BIGSERIAL PRIMARY KEY,
    flight_number    VARCHAR(20),
    callsign         VARCHAR(20),
    icao24           CHAR(6),
    airline_iata     VARCHAR(5),
    origin_iata      VARCHAR(5),
    destination_iata VARCHAR(5),
    aircraft_type    VARCHAR(50),
    flight_date      DATE NOT NULL,
    scheduled_dep    TIMESTAMPTZ,
    actual_dep       TIMESTAMPTZ,
    actual_arr       TIMESTAMPTZ,
    duration_min     INTEGER,
    -- source flags
    has_schedule     BOOLEAN DEFAULT false,
    has_rtlsdr       BOOLEAN DEFAULT false,
    has_fr24         BOOLEAN DEFAULT false,
    has_fa           BOOLEAN DEFAULT false,
    track_source     VARCHAR(10),  -- 'rtlsdr'|'fr24'|'fa'|null
    track_points     INTEGER,
    -- source keys
    schedule_id      BIGINT,
    fr24_track_id    BIGINT,
    fa_track_id      BIGINT,
    rtlsdr_flight_id BIGINT,
    updated_at       TIMESTAMPTZ DEFAULT now()
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_mart_flights_date_callsign ON fr24_mart.flights (flight_date, callsign);
CREATE INDEX IF NOT EXISTS idx_mart_flights_date ON fr24_mart.flights (flight_date);

-- Unified track points (best source)
CREATE TABLE IF NOT EXISTS fr24_mart.track_points (
    id          BIGSERIAL PRIMARY KEY,
    flight_id   BIGINT NOT NULL REFERENCES fr24_mart.flights(id) ON DELETE CASCADE,
    observed_at TIMESTAMPTZ NOT NULL,
    lat         DOUBLE PRECISION NOT NULL,
    lon         DOUBLE PRECISION NOT NULL,
    altitude_m  INTEGER,
    speed_kt    INTEGER,
    heading     SMALLINT,
    source      VARCHAR(10)
);
CREATE INDEX IF NOT EXISTS idx_mart_track_points_flight ON fr24_mart.track_points (flight_id, observed_at);
CREATE INDEX IF NOT EXISTS idx_mart_track_points_geo ON fr24_mart.track_points (lat, lon);

-- Noise grid (0.01° cells)
CREATE TABLE IF NOT EXISTS fr24_mart.noise_grid (
    id             BIGSERIAL PRIMARY KEY,
    grid_lat       NUMERIC(7,4) NOT NULL,
    grid_lon       NUMERIC(7,4) NOT NULL,
    period_date    DATE NOT NULL,
    flight_count   INTEGER DEFAULT 0,
    noise_score    FLOAT DEFAULT 0,
    avg_altitude_m FLOAT,
    updated_at     TIMESTAMPTZ DEFAULT now(),
    UNIQUE (grid_lat, grid_lon, period_date)
);
CREATE INDEX IF NOT EXISTS idx_noise_grid_date ON fr24_mart.noise_grid (period_date);

-- Source coverage metrics
CREATE TABLE IF NOT EXISTS fr24_mart.source_coverage (
    coverage_date  DATE PRIMARY KEY,
    total_schedule INTEGER DEFAULT 0,
    with_rtlsdr    INTEGER DEFAULT 0,
    with_fr24      INTEGER DEFAULT 0,
    with_fa        INTEGER DEFAULT 0,
    schedule_only  INTEGER DEFAULT 0,
    rtlsdr_pct     FLOAT,
    fr24_pct       FLOAT,
    fa_pct         FLOAT,
    updated_at     TIMESTAMPTZ DEFAULT now()
);
