-- 003: 선박 위치 이력 + OSINT 피드 + 위성 TLE 테이블
-- 리플레이 및 분석용 시계열 데이터 저장

SET search_path TO kcg, public;

-- ═══════════════════════════════════════════
-- 선박 위치 이력 (AIS / signal-batch)
-- ═══════════════════════════════════════════
CREATE TABLE IF NOT EXISTS ship_positions (
    id              BIGSERIAL PRIMARY KEY,
    mmsi            VARCHAR(9) NOT NULL,
    name            VARCHAR(128),
    position        geometry(Point, 4326) NOT NULL,
    heading         DOUBLE PRECISION,
    speed           DOUBLE PRECISION,         -- knots
    course          DOUBLE PRECISION,         -- COG
    category        VARCHAR(16),              -- warship, carrier, destroyer, tanker, cargo, ...
    flag            VARCHAR(4),               -- ISO 국가코드
    typecode        VARCHAR(16),
    type_desc       VARCHAR(128),
    imo             VARCHAR(16),
    call_sign       VARCHAR(16),
    status          VARCHAR(64),              -- Under way, Anchored, ...
    destination     VARCHAR(128),
    draught         DOUBLE PRECISION,
    length          DOUBLE PRECISION,
    width           DOUBLE PRECISION,
    source          VARCHAR(16) NOT NULL,     -- spg, signal-batch, sample
    region          VARCHAR(16) NOT NULL,     -- middleeast, korea
    collected_at    TIMESTAMP NOT NULL DEFAULT NOW(),
    last_seen       TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_ship_pos_geom ON ship_positions USING GIST (position);
CREATE INDEX IF NOT EXISTS idx_ship_pos_collected ON ship_positions (collected_at);
CREATE INDEX IF NOT EXISTS idx_ship_pos_region_time ON ship_positions (region, collected_at);
CREATE INDEX IF NOT EXISTS idx_ship_pos_mmsi ON ship_positions (mmsi, collected_at);

-- ═══════════════════════════════════════════
-- OSINT 피드 (GDELT, Google News, CENTCOM)
-- ═══════════════════════════════════════════
CREATE TABLE IF NOT EXISTS osint_feeds (
    id              BIGSERIAL PRIMARY KEY,
    title           TEXT NOT NULL,
    source          VARCHAR(64) NOT NULL,     -- gdelt, google-news-ko, google-news-en, centcom
    source_url      TEXT,
    category        VARCHAR(32),              -- military, oil, diplomacy, shipping, nuclear, ...
    language        VARCHAR(8),               -- ko, en
    focus           VARCHAR(16),              -- iran, korea
    image_url       TEXT,
    position        geometry(Point, 4326),    -- nullable (위치 추출 가능 시)
    published_at    TIMESTAMP,                -- 원본 기사 발행 시각
    collected_at    TIMESTAMP NOT NULL DEFAULT NOW(),
    UNIQUE(source, source_url)                -- 중복 방지
);

CREATE INDEX IF NOT EXISTS idx_osint_feeds_collected ON osint_feeds (collected_at);
CREATE INDEX IF NOT EXISTS idx_osint_feeds_focus ON osint_feeds (focus, collected_at);
CREATE INDEX IF NOT EXISTS idx_osint_feeds_category ON osint_feeds (category);
CREATE INDEX IF NOT EXISTS idx_osint_feeds_geom ON osint_feeds USING GIST (position);

-- ═══════════════════════════════════════════
-- 위성 TLE (CelesTrak)
-- ═══════════════════════════════════════════
CREATE TABLE IF NOT EXISTS satellite_tle (
    id              BIGSERIAL PRIMARY KEY,
    norad_id        INTEGER NOT NULL,
    name            VARCHAR(128) NOT NULL,
    tle_line1       VARCHAR(70) NOT NULL,
    tle_line2       VARCHAR(70) NOT NULL,
    category        VARCHAR(20),              -- reconnaissance, communications, navigation, weather, other
    tle_group       VARCHAR(32),              -- military, gps-ops, geo, weather, stations
    epoch           TIMESTAMP,                -- TLE epoch (궤도 기준 시각)
    collected_at    TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_satellite_tle_norad ON satellite_tle (norad_id, collected_at);
CREATE INDEX IF NOT EXISTS idx_satellite_tle_collected ON satellite_tle (collected_at);
CREATE INDEX IF NOT EXISTS idx_satellite_tle_category ON satellite_tle (category);
