-- =============================================================================
-- Migration 016: Fahrzeugbuchungen (Vehicle Booking System)
-- Allows members to book fire department vehicles for internal use, external
-- events, maintenance slots and reservations. Includes per-user iCal feeds.
-- Depends on: 001_create_users_table.sql (uuid-ossp, pgcrypto extensions,
--             users table, update_updated_at_column trigger function)
--             005_create_fahrzeuge.sql (fahrzeuge table)
-- =============================================================================

-- -----------------------------------------------------------------------------
-- 1. ENUM: booking type
-- Uses DO-block for idempotent creation (PostgreSQL has no CREATE TYPE IF NOT EXISTS)
-- -----------------------------------------------------------------------------
DO $$
BEGIN
    CREATE TYPE fahrzeug_buchung_art AS ENUM (
        'intern',
        'extern',
        'wartung',
        'reservierung',
        'sonstiges'
    );
EXCEPTION
    WHEN duplicate_object THEN NULL;
END
$$;

-- -----------------------------------------------------------------------------
-- 2. Vehicle bookings table
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS fahrzeug_buchungen (
    id                  UUID                 PRIMARY KEY DEFAULT uuid_generate_v4(),
    fahrzeug_id         UUID                 NOT NULL REFERENCES fahrzeuge(id) ON DELETE CASCADE,
    titel               VARCHAR(500)         NOT NULL,
    beschreibung        TEXT,
    beginn              TIMESTAMPTZ          NOT NULL,
    ende                TIMESTAMPTZ          NOT NULL,
    buchungs_art        fahrzeug_buchung_art NOT NULL DEFAULT 'intern',
    gebucht_von         UUID                 NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
    -- kontakt fields are relevant for external bookings
    kontakt_person      VARCHAR(255),
    kontakt_telefon     VARCHAR(50),
    abgesagt            BOOLEAN              NOT NULL DEFAULT FALSE,
    abgesagt_grund      TEXT,
    erstellt_am         TIMESTAMPTZ          NOT NULL DEFAULT NOW(),
    aktualisiert_am     TIMESTAMPTZ          NOT NULL DEFAULT NOW(),

    CONSTRAINT buchung_ende_nach_beginn CHECK (ende > beginn)
);

CREATE INDEX IF NOT EXISTS idx_fahrzeug_buchungen_fahrzeug_id
    ON fahrzeug_buchungen(fahrzeug_id);
CREATE INDEX IF NOT EXISTS idx_fahrzeug_buchungen_beginn
    ON fahrzeug_buchungen(beginn);
CREATE INDEX IF NOT EXISTS idx_fahrzeug_buchungen_ende
    ON fahrzeug_buchungen(ende);
CREATE INDEX IF NOT EXISTS idx_fahrzeug_buchungen_gebucht_von
    ON fahrzeug_buchungen(gebucht_von);
CREATE INDEX IF NOT EXISTS idx_fahrzeug_buchungen_abgesagt
    ON fahrzeug_buchungen(abgesagt) WHERE abgesagt = FALSE;
-- Compound index for availability / overlap checks (fahrzeug + time range)
CREATE INDEX IF NOT EXISTS idx_fahrzeug_buchungen_fahrzeug_beginn_ende
    ON fahrzeug_buchungen(fahrzeug_id, beginn, ende);

CREATE TRIGGER update_fahrzeug_buchungen_aktualisiert_am
    BEFORE UPDATE ON fahrzeug_buchungen
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- -----------------------------------------------------------------------------
-- 3. Per-user iCal subscription tokens for the vehicle booking calendar
-- One token per user — the feed returns all bookings the user has access to.
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS fahrzeug_ical_tokens (
    id                   UUID        PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id              UUID        NOT NULL 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,

    -- one token per user for the full vehicle booking feed
    UNIQUE (user_id)
);

CREATE INDEX IF NOT EXISTS idx_fahrzeug_ical_tokens_token
    ON fahrzeug_ical_tokens(token);
