-- Tier 2 Block F — reminders + broadcasts.
--
-- The Tier 2 plan called this the messages pipeline. Two tables:
--
--   scheduled_messages  — one row per message envelope. Status moves
--                         scheduled -> sending -> sent (or cancelled / failed).
--   message_deliveries  — one row per recipient. Lets a partial-failure
--                         batch keep the rows that did succeed and surface
--                         the rest in the UI.
--
-- The scheduler worker (cmd/notifier) polls scheduled_messages by
-- send_at; the index supports that without a sequential scan even on
-- thousands of pending rows.

DO $$ BEGIN
    CREATE TYPE message_audience AS ENUM ('all', 'attending', 'pending', 'declined', 'maybe');
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE message_channel AS ENUM ('email', 'sms', 'both');
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

DO $$ BEGIN
    CREATE TYPE message_status AS ENUM ('draft', 'scheduled', 'sending', 'sent', 'cancelled', 'failed');
EXCEPTION WHEN duplicate_object THEN NULL; END $$;

CREATE TABLE IF NOT EXISTS scheduled_messages (
    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    event_id        UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
    send_at         TIMESTAMPTZ NOT NULL,
    audience        message_audience NOT NULL,
    channel         message_channel NOT NULL,
    -- template_key tags the auto-seeded reminders ('reminder_7d',
    -- 'reminder_1d', 'reminder_dayof', 'last_call'). NULL for hand-
    -- composed broadcasts.
    template_key    TEXT,
    subject         TEXT,
    body            TEXT NOT NULL,
    status          message_status NOT NULL DEFAULT 'draft',
    sent_at         TIMESTAMPTZ,
    recipient_count INTEGER,
    -- created_by is the user who scheduled or composed the message.
    -- NULL for system-seeded auto-reminders.
    created_by      UUID REFERENCES users(id) ON DELETE SET NULL,
    created_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at      TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- The scheduler's hot query: "what's due right now?" Partial index keeps
-- it small even on events with hundreds of historical sent messages.
CREATE INDEX IF NOT EXISTS idx_messages_due
    ON scheduled_messages (send_at)
    WHERE status = 'scheduled';

-- "Show me this event's communications history" — used by the
-- Communications tab. Sorted newest-first so the index covers ORDER BY.
CREATE INDEX IF NOT EXISTS idx_messages_event
    ON scheduled_messages (event_id, created_at DESC);

CREATE TABLE IF NOT EXISTS message_deliveries (
    message_id  UUID NOT NULL REFERENCES scheduled_messages(id) ON DELETE CASCADE,
    guest_id    UUID NOT NULL REFERENCES guests(id) ON DELETE CASCADE,
    status      TEXT NOT NULL,  -- 'pending' | 'sent' | 'bounced' | 'skipped' | 'failed'
    sent_at     TIMESTAMPTZ,
    error       TEXT,
    PRIMARY KEY (message_id, guest_id)
);

-- "Which delivers succeeded for this message?" — used by the per-message
-- drill-down in the UI.
CREATE INDEX IF NOT EXISTS idx_deliveries_message
    ON message_deliveries (message_id, status);
