-- Multi-Event Invitation App Database Schema
-- PostgreSQL Migration Script
-- Created: 2026-02-23

-- ============================================
-- STEP 1: Enable UUID Extension
-- ============================================
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

-- ============================================
-- STEP 2: Create Users Table
-- ============================================
-- Track users who can manage events
CREATE TABLE IF NOT EXISTS users (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    email TEXT NOT NULL UNIQUE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_email ON users(email);

-- Migrate existing owners from guests table to users (optional, run after creating guests table)
-- INSERT INTO users (email) SELECT DISTINCT owner FROM guests WHERE owner IS NOT NULL AND owner != 'self-service' ON CONFLICT DO NOTHING;

-- ============================================
-- STEP 3: Create Events Table
-- ============================================
-- Store multiple events
CREATE TABLE IF NOT EXISTS events (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL,
    date TIMESTAMP WITH TIME ZONE,
    location TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_events_created_at ON events(created_at);

-- ============================================
-- STEP 4: Create Event Members Table (Authorization)
-- ============================================
-- Track which users are members of which events and their roles
CREATE TABLE IF NOT EXISTS event_members (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role TEXT NOT NULL DEFAULT 'admin' CHECK (role IN ('admin', 'editor', 'viewer')),
    display_name TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(event_id, user_id)
);

CREATE INDEX idx_event_members_event_id ON event_members(event_id);
CREATE INDEX idx_event_members_user_id ON event_members(user_id);
CREATE INDEX idx_event_members_event_user ON event_members(event_id, user_id);

-- ============================================
-- STEP 5: Create Guests Table (Refactored)
-- ============================================
-- Store guest information scoped by event
CREATE TABLE IF NOT EXISTS guests_v2 (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
    added_by_user_id UUID NOT NULL REFERENCES users(id),
    
    -- Guest Information
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL,
    email TEXT,
    phone_number TEXT,
    
    -- RSVP & Preferences
    rsvp_status TEXT NOT NULL DEFAULT 'invited' CHECK (rsvp_status IN ('invited', 'confirmed', 'declined')),
    meal_preference TEXT,
    
    -- Plus One
    has_plus_one BOOLEAN DEFAULT FALSE,
    plus_one_name TEXT,
    
    -- Event Details
    table_number TEXT,
    side TEXT,  -- e.g. "groom side" / "bride side" / "Dvir side" / "Vered side"
    
    -- Source Information
    owner_email TEXT,  -- Email of person who added this guest
    source TEXT DEFAULT 'manual' CHECK (source IN ('google', 'manual', 'self-service')),
    
    -- Notes & Metadata
    notes TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- Indexes for performance
CREATE INDEX idx_guests_event_id ON guests_v2(event_id);
CREATE INDEX idx_guests_added_by_user_id ON guests_v2(added_by_user_id);
CREATE INDEX idx_guests_event_user ON guests_v2(event_id, added_by_user_id);
CREATE INDEX idx_guests_phone_number ON guests_v2(phone_number);
CREATE INDEX idx_guests_event_phone ON guests_v2(event_id, phone_number);
CREATE INDEX idx_guests_event_status ON guests_v2(event_id, rsvp_status);
CREATE INDEX idx_guests_owner_email ON guests_v2(event_id, owner_email);
CREATE INDEX idx_guests_source ON guests_v2(event_id, source);

-- Trigger for auto-updating updated_at on guests_v2
CREATE OR REPLACE FUNCTION update_guests_v2_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';

CREATE TRIGGER update_guests_v2_timestamp 
    BEFORE UPDATE ON guests_v2
    FOR EACH ROW
    EXECUTE FUNCTION update_guests_v2_updated_at();

-- ============================================
-- STEP 6: Migration from Old Schema (Optional)
-- ============================================
-- This section is optional and only needed if migrating existing data

-- Create migration function to handle existing guests table
-- Run this if you have existing data in the old guests table

/*
DO $$
DECLARE
    default_event_id UUID;
    default_user_id UUID;
BEGIN
    -- Create a default event for migration
    INSERT INTO events (name, date, location)
    VALUES ('Migrated Wedding', NOW(), 'Unknown')
    RETURNING id INTO default_event_id;
    
    -- Create default user for unmapped owners
    INSERT INTO users (email)
    VALUES ('admin@example.com')
    ON CONFLICT DO NOTHING;
    
    SELECT id INTO default_user_id FROM users WHERE email = 'admin@example.com';
    
    -- Migrate data from old guests table to new one
    INSERT INTO guests_v2 (event_id, added_by_user_id, first_name, last_name, phone, side, status, notes)
    SELECT 
        default_event_id,
        COALESCE(
            (SELECT id FROM users WHERE email = guests.owner),
            default_user_id
        ),
        guests.first_name,
        guests.last_name,
        COALESCE(guests.phone_number, ''),
        NULL,
        CASE 
            WHEN guests.rsvp_status = 'accepted' THEN 'confirmed'
            WHEN guests.rsvp_status = 'declined' THEN 'declined'
            ELSE 'invited'
        END,
        COALESCE(
            'Meal: ' || guests.meal_preference || '; Plus-one: ' || guests.plus_one_name,
            notes
        )
    FROM guests;
    
    -- Create event_members record for default user
    INSERT INTO event_members (event_id, user_id, role, display_name)
    VALUES (default_event_id, default_user_id, 'admin', 'Admin')
    ON CONFLICT DO NOTHING;
END $$;
*/

-- ============================================
-- STEP 7: ALTER Guests Table (if already exists - add missing columns)
-- ============================================
-- Safe migration that handles existing data

-- Migration logic using a PL/pgSQL block
DO $$
BEGIN
    -- Check if column exists before creating/renaming
    -- If rsvp_status doesn't exist, handle the rename or creation
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'rsvp_status'
    ) THEN
        -- If old status column exists, rename it
        IF EXISTS (
            SELECT FROM information_schema.columns 
            WHERE table_name = 'guests_v2' AND column_name = 'status'
        ) THEN
            ALTER TABLE guests_v2 RENAME COLUMN status TO rsvp_status;
        ELSE
            -- Add rsvp_status column with default
            ALTER TABLE guests_v2 ADD COLUMN rsvp_status TEXT DEFAULT 'invited';
        END IF;
    END IF;
    
    -- Handle phone_number migration
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'phone_number'
    ) THEN
        IF EXISTS (
            SELECT FROM information_schema.columns 
            WHERE table_name = 'guests_v2' AND column_name = 'phone'
        ) THEN
            ALTER TABLE guests_v2 RENAME COLUMN phone TO phone_number;
        ELSE
            ALTER TABLE guests_v2 ADD COLUMN phone_number TEXT;
        END IF;
    END IF;
    
    -- Add other missing columns
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'email'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN email TEXT;
    END IF;
    
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'meal_preference'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN meal_preference TEXT;
    END IF;
    
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'has_plus_one'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN has_plus_one BOOLEAN DEFAULT FALSE;
    END IF;
    
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'plus_one_name'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN plus_one_name TEXT;
    END IF;
    
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'table_number'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN table_number TEXT;
    END IF;
    
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'owner_email'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN owner_email TEXT;
    END IF;
    
    IF NOT EXISTS (
        SELECT FROM information_schema.columns 
        WHERE table_name = 'guests_v2' AND column_name = 'source'
    ) THEN
        ALTER TABLE guests_v2 ADD COLUMN source TEXT DEFAULT 'manual';
    END IF;

    RAISE NOTICE 'Migration completed successfully';
END $$;

-- Update CHECK constraint for rsvp_status if needed
DO $$
BEGIN
    -- Drop old constraint if it exists
    ALTER TABLE guests_v2 DROP CONSTRAINT IF EXISTS guests_v2_status_check;
    -- Add new constraint
    ALTER TABLE guests_v2 ADD CONSTRAINT guests_v2_rsvp_status_check 
        CHECK (rsvp_status IN ('invited', 'confirmed', 'declined'));
EXCEPTION WHEN OTHERS THEN
    -- Constraint might already exist, that's okay
    NULL;
END $$;

-- Add source constraint
DO $$
BEGIN
    ALTER TABLE guests_v2 ADD CONSTRAINT guests_v2_source_check 
        CHECK (source IN ('google', 'manual', 'self-service'));
EXCEPTION WHEN OTHERS THEN
    NULL;
END $$;

-- Add missing indexes if they don't exist
CREATE INDEX IF NOT EXISTS idx_guests_owner_email ON guests_v2(event_id, owner_email);
CREATE INDEX IF NOT EXISTS idx_guests_source ON guests_v2(event_id, source);
CREATE INDEX IF NOT EXISTS idx_guests_phone_number ON guests_v2(phone_number);
CREATE INDEX IF NOT EXISTS idx_guests_event_phone_new ON guests_v2(event_id, phone_number);


-- ============================================
-- STEP 15: Add WhatsApp Template Fields (Migration)
-- ============================================
-- Add WhatsApp-related columns to events table for wedding invitation template

DO $$
BEGIN
    ALTER TABLE events ADD COLUMN partner1_name TEXT;
EXCEPTION WHEN OTHERS THEN
    NULL;
END $$;

DO $$
BEGIN
    ALTER TABLE events ADD COLUMN partner2_name TEXT;
EXCEPTION WHEN OTHERS THEN
    NULL;
END $$;

DO $$
BEGIN
    ALTER TABLE events ADD COLUMN venue TEXT;
EXCEPTION WHEN OTHERS THEN
    NULL;
END $$;

DO $$
BEGIN
    ALTER TABLE events ADD COLUMN event_time TEXT;
EXCEPTION WHEN OTHERS THEN
    NULL;
END $$;

DO $$
BEGIN
    ALTER TABLE events ADD COLUMN guest_link TEXT;
EXCEPTION WHEN OTHERS THEN
    NULL;
END $$;

-- Create index for query efficiency
CREATE INDEX IF NOT EXISTS idx_events_guest_link ON events(guest_link);

-- ============================================
-- RSVP Token table
-- Per-guest per-event tokens embedded in WhatsApp CTA button URLs
-- ============================================
CREATE TABLE IF NOT EXISTS rsvp_tokens (
    token       TEXT PRIMARY KEY,
    event_id    UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
    guest_id    UUID REFERENCES guests_v2(id) ON DELETE SET NULL,
    phone       TEXT,
    created_at  TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    expires_at  TIMESTAMP WITH TIME ZONE,
    used_at     TIMESTAMP WITH TIME ZONE
);
CREATE INDEX IF NOT EXISTS idx_rsvp_tokens_event_id ON rsvp_tokens(event_id);
CREATE INDEX IF NOT EXISTS idx_rsvp_tokens_guest_id ON rsvp_tokens(guest_id);
