-- ============================================================
-- willhaben-tracker — initial schema migration
-- ============================================================

-- -----------------------------------------------------------
-- 1. users (whitelisted Telegram users)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS users (
    id          uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    telegram_id bigint UNIQUE NOT NULL,
    username    text,
    first_name  text,
    is_admin    boolean NOT NULL DEFAULT false,
    is_active   boolean NOT NULL DEFAULT true,
    created_at  timestamptz NOT NULL DEFAULT now()
);

-- -----------------------------------------------------------
-- 2. search_queries (saved searches per user)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS search_queries (
    id               uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id          uuid REFERENCES users(id) ON DELETE CASCADE NOT NULL,
    keyword          text NOT NULL,
    interval_minutes int NOT NULL DEFAULT 60,
    is_active        boolean NOT NULL DEFAULT true,
    last_scraped_at  timestamptz,
    created_at       timestamptz NOT NULL DEFAULT now()
);

-- -----------------------------------------------------------
-- 3. ads (raw ad snapshots, globally deduplicated by wh_ad_id)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS ads (
    id            uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    wh_ad_id      text UNIQUE NOT NULL,
    raw_json      jsonb NOT NULL,
    title         text NOT NULL,
    price         numeric,
    location      text,
    url           text,
    published_at  timestamptz,
    first_seen_at timestamptz NOT NULL DEFAULT now()
);

-- -----------------------------------------------------------
-- 4. query_ads (junction: which query found which ad)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS query_ads (
    search_query_id uuid REFERENCES search_queries(id) ON DELETE CASCADE NOT NULL,
    ad_id           uuid REFERENCES ads(id) ON DELETE CASCADE NOT NULL,
    first_seen_at   timestamptz NOT NULL DEFAULT now(),
    is_notified     boolean NOT NULL DEFAULT false,
    PRIMARY KEY (search_query_id, ad_id)
);

-- -----------------------------------------------------------
-- 5. notifications (audit log of sent Telegram messages)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS notifications (
    id         uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id    uuid REFERENCES users(id) ON DELETE CASCADE NOT NULL,
    ad_id      uuid REFERENCES ads(id) ON DELETE SET NULL,
    message_id int,
    sent_at    timestamptz NOT NULL DEFAULT now()
);

-- -----------------------------------------------------------
-- 6. scrape_logs (worker health / debugging)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS scrape_logs (
    id            uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    search_query_id uuid REFERENCES search_queries(id) ON DELETE CASCADE NOT NULL,
    status        text NOT NULL CHECK (status IN ('success', 'error', 'rate_limited')),
    ads_found     int NOT NULL DEFAULT 0,
    new_ads       int NOT NULL DEFAULT 0,
    error_message text,
    scraped_at    timestamptz NOT NULL DEFAULT now()
);

-- ============================================================
-- Indexes
-- ============================================================

-- Users: fast lookup by telegram_id (unique constraint already implies an index)

-- Search queries: user membership lookups
CREATE INDEX IF NOT EXISTS idx_search_queries_user_id ON search_queries(user_id);

-- Scheduler polling: active queries ordered by last scraped time
CREATE INDEX IF NOT EXISTS idx_search_queries_active_scraped
    ON search_queries(is_active, last_scraped_at) WHERE is_active = true;

-- Notifier lookups: un-notified ads per query
CREATE INDEX IF NOT EXISTS idx_query_ads_notified
    ON query_ads(search_query_id, is_notified) WHERE is_notified = false;

-- Notifications: recent messages per user
CREATE INDEX IF NOT EXISTS idx_notifications_user_sent
    ON notifications(user_id, sent_at DESC);

-- Scrape logs: latest runs per query
CREATE INDEX IF NOT EXISTS idx_scrape_logs_query_at
    ON scrape_logs(search_query_id, scraped_at DESC);
