-- =============================================================================
-- Migration 015: Veranstaltungen (Events / General Calendar)
-- General event calendar for Feuerwehr Dashboard, separate from the training
-- calendar (uebungen). Supports categories, RSVPs, and iCal subscriptions.
-- Depends on: 001_create_users_table.sql (uuid-ossp, pgcrypto extensions,
--             users table, update_updated_at_column trigger function)
-- =============================================================================

CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- -----------------------------------------------------------------------------
-- 1. Event categories table
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS veranstaltung_kategorien (
    id              UUID         PRIMARY KEY DEFAULT uuid_generate_v4(),
    name            VARCHAR(255) NOT NULL,
    beschreibung    TEXT,
    farbe           VARCHAR(7)   NOT NULL DEFAULT '#1976d2',   -- hex colour for UI chips
    icon            VARCHAR(100),                              -- MUI icon name, e.g. 'Event', 'FireTruck'
    erstellt_von    UUID         REFERENCES users(id) ON DELETE SET NULL,
    erstellt_am     TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    aktualisiert_am TIMESTAMPTZ  NOT NULL DEFAULT NOW()
);

CREATE TRIGGER update_veranstaltung_kategorien_aktualisiert_am
    BEFORE UPDATE ON veranstaltung_kategorien
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- -----------------------------------------------------------------------------
-- 2. Main events table
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS veranstaltungen (
    id                      UUID         PRIMARY KEY DEFAULT uuid_generate_v4(),
    titel                   VARCHAR(500) NOT NULL,
    beschreibung            TEXT,
    ort                     VARCHAR(500),
    ort_url                 VARCHAR(1000),                     -- optional maps/navigation link
    kategorie_id            UUID         REFERENCES veranstaltung_kategorien(id) ON DELETE SET NULL,
    datum_von               TIMESTAMPTZ  NOT NULL,
    datum_bis               TIMESTAMPTZ  NOT NULL,
    ganztaegig              BOOLEAN      NOT NULL DEFAULT FALSE,
    -- zielgruppen: array of Authentik group names, e.g. '{dashboard_mitglied,dashboard_jugend}'
    zielgruppen             TEXT[]       NOT NULL DEFAULT '{}',
    alle_gruppen            BOOLEAN      NOT NULL DEFAULT FALSE, -- TRUE = visible to all members
    max_teilnehmer          INTEGER      CHECK (max_teilnehmer > 0),
    anmeldung_erforderlich  BOOLEAN      NOT NULL DEFAULT FALSE,
    anmeldung_bis           TIMESTAMPTZ,
    erstellt_von            UUID         NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
    abgesagt                BOOLEAN      NOT NULL DEFAULT FALSE,
    abgesagt_grund          TEXT,
    abgesagt_am             TIMESTAMPTZ,
    erstellt_am             TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    aktualisiert_am         TIMESTAMPTZ  NOT NULL DEFAULT NOW(),

    CONSTRAINT veranstaltung_datum_reihenfolge CHECK (datum_bis >= datum_von)
);

CREATE INDEX IF NOT EXISTS idx_veranstaltungen_datum_von
    ON veranstaltungen(datum_von);
CREATE INDEX IF NOT EXISTS idx_veranstaltungen_datum_bis
    ON veranstaltungen(datum_bis);
CREATE INDEX IF NOT EXISTS idx_veranstaltungen_kategorie_id
    ON veranstaltungen(kategorie_id);
CREATE INDEX IF NOT EXISTS idx_veranstaltungen_abgesagt
    ON veranstaltungen(abgesagt) WHERE abgesagt = FALSE;
CREATE INDEX IF NOT EXISTS idx_veranstaltungen_alle_gruppen
    ON veranstaltungen(alle_gruppen);
-- Compound index for the most common calendar-range query
CREATE INDEX IF NOT EXISTS idx_veranstaltungen_datum_von_bis
    ON veranstaltungen(datum_von, datum_bis);

CREATE TRIGGER update_veranstaltungen_aktualisiert_am
    BEFORE UPDATE ON veranstaltungen
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- -----------------------------------------------------------------------------
-- 3. RSVP / attendance table
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS veranstaltung_teilnahmen (
    veranstaltung_id    UUID        NOT NULL REFERENCES veranstaltungen(id) ON DELETE CASCADE,
    user_id             UUID        NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    -- status values: zugesagt, abgesagt, erschienen, unbekannt
    status              VARCHAR(20) NOT NULL DEFAULT 'unbekannt',
    notiz               VARCHAR(500),
    aktualisiert_am     TIMESTAMPTZ NOT NULL DEFAULT NOW(),

    PRIMARY KEY (veranstaltung_id, user_id)
);

CREATE INDEX IF NOT EXISTS idx_veranstaltung_teilnahmen_veranstaltung_id
    ON veranstaltung_teilnahmen(veranstaltung_id);
CREATE INDEX IF NOT EXISTS idx_veranstaltung_teilnahmen_user_id
    ON veranstaltung_teilnahmen(user_id);

-- -----------------------------------------------------------------------------
-- 4. Per-user iCal subscription tokens
-- One token per user — covers the full events calendar feed for that user.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS veranstaltung_ical_tokens (
    user_id              UUID        PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
    token                VARCHAR(128) UNIQUE NOT NULL DEFAULT encode(gen_random_bytes(32), 'hex'),
    erstellt_am          TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    zuletzt_verwendet_am TIMESTAMPTZ
);

CREATE INDEX IF NOT EXISTS idx_veranstaltung_ical_tokens_token
    ON veranstaltung_ical_tokens(token);

-- -----------------------------------------------------------------------------
-- 5. Seed default event categories
-- -----------------------------------------------------------------------------
INSERT INTO veranstaltung_kategorien (name, farbe, icon) VALUES
    ('Allgemein',        '#1976d2', 'Event'),
    ('Ausbildung',       '#2e7d32', 'School'),
    ('Gesellschaft',     '#e65100', 'People'),
    ('Feuerwehrjugend',  '#f57c00', 'ChildCare'),
    ('Kommando',         '#6a1b9a', 'Shield')
ON CONFLICT DO NOTHING;
