-- discgod schema (reference copy — the server applies this itself via
-- discgod_ingest.ensure_schema() on startup). Additive: it reuses the existing
-- marketwatcher mp_* tables verbatim and adds one watchlist table.
--
-- Apply manually if you like:  psql discogs_full -f schema.sql

-- Sellers ever seen, with latest reputation stats.
CREATE TABLE IF NOT EXISTS mp_seller (
    seller_id      BIGINT PRIMARY KEY,
    username       TEXT NOT NULL,
    rating         NUMERIC(3,1),
    rating_percent NUMERIC(5,2),
    ratings_count  INTEGER,
    ships_from     TEXT,
    first_seen     TIMESTAMPTZ DEFAULT now(),
    last_seen      TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_mp_seller_username ON mp_seller (username);

-- One row per marketplace listing (unique physical copy). release_id joins
-- straight to your XML `release` table.
CREATE TABLE IF NOT EXISTS mp_listing (
    item_id           BIGINT PRIMARY KEY,
    release_id        BIGINT NOT NULL,
    seller_id         BIGINT,
    seller_username   TEXT,
    title             TEXT,
    label             TEXT,
    cat_no            TEXT,
    media_condition   TEXT,
    sleeve_condition  TEXT,
    notes             TEXT,
    price_value       NUMERIC(12,2),
    price_currency    TEXT,
    shipping_value    NUMERIC(12,2),
    converted_value   NUMERIC(12,2),
    have_count        INTEGER,
    want_count        INTEGER,
    ships_from        TEXT,
    status            TEXT NOT NULL DEFAULT 'active',  -- active | gone
    gone_at           TIMESTAMPTZ,
    first_seen        TIMESTAMPTZ DEFAULT now(),
    last_seen         TIMESTAMPTZ DEFAULT now(),
    times_seen        INTEGER DEFAULT 1,
    last_crawl_id     TEXT
);
CREATE INDEX IF NOT EXISTS idx_mp_listing_release ON mp_listing (release_id);
CREATE INDEX IF NOT EXISTS idx_mp_listing_seller  ON mp_listing (seller_username, status);
CREATE INDEX IF NOT EXISTS idx_mp_listing_seen    ON mp_listing (last_seen DESC);

-- Append-only state-change history per listing.
-- event: listed | price_change | condition_change | gone | relisted
CREATE TABLE IF NOT EXISTS mp_listing_event (
    id          BIGSERIAL PRIMARY KEY,
    item_id     BIGINT NOT NULL,
    release_id  BIGINT,
    seller_username TEXT,
    event       TEXT NOT NULL,
    old_price   NUMERIC(12,2),
    new_price   NUMERIC(12,2),
    currency    TEXT,
    details     JSONB,
    recorded_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_mp_event_item    ON mp_listing_event (item_id, recorded_at DESC);
CREATE INDEX IF NOT EXISTS idx_mp_event_type    ON mp_listing_event (event, recorded_at DESC);
CREATE INDEX IF NOT EXISTS idx_mp_event_release ON mp_listing_event (release_id);

-- Inventory-size time series per seller. source = 'api_inventory' for discgod
-- (the authoritative pagination total from the Discogs API).
CREATE TABLE IF NOT EXISTS mp_seller_snapshot (
    id             BIGSERIAL PRIMARY KEY,
    seller_id      BIGINT,
    username       TEXT NOT NULL,
    total_listings BIGINT,
    source         TEXT NOT NULL,
    filter_key     TEXT,
    filter_params  JSONB,
    captured_at    TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_mp_snapshot_series
    ON mp_seller_snapshot (username, source, filter_key, captured_at DESC);

-- Provenance: every captured inventory page.
CREATE TABLE IF NOT EXISTS mp_page_log (
    id            BIGSERIAL PRIMARY KEY,
    url           TEXT,
    page_type     TEXT,                 -- 'api_inventory' for discgod
    seller_page   TEXT,
    params        JSONB,
    page          INTEGER,
    total_results BIGINT,
    item_count    INTEGER,
    item_ids      BIGINT[],
    new_items     INTEGER,
    price_changes INTEGER,
    crawl_id      TEXT,
    scraped_at    TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_mp_page_log_time ON mp_page_log (scraped_at DESC);

-- discgod watchlist: who to auto-crawl. Shared by the extension popup and the
-- headless cron crawler.
CREATE TABLE IF NOT EXISTS discgod_seller_watch (
    username           TEXT PRIMARY KEY,
    seller_id          BIGINT,
    enabled            BOOLEAN DEFAULT TRUE,
    note               TEXT,
    filter_params      JSONB,
    added_at           TIMESTAMPTZ DEFAULT now(),
    last_crawled_at    TIMESTAMPTZ,
    last_listing_count INTEGER,
    last_status        TEXT
);
CREATE INDEX IF NOT EXISTS idx_discgod_watch_enabled ON discgod_seller_watch (enabled);
