-- V009: Add Performance Optimization Indexes
-- Created: 2025-10-01
-- Purpose: Optimize frequently queried tables with additional indexes
-- NOTE: All indexes use IF NOT EXISTS to handle cases where they may already exist

-- ==================== Users Table ====================

-- Index for email lookup (already exists as unique, but adding comment)
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'users_email_key') THEN
        COMMENT ON INDEX users_email_key IS 'Optimized index for user authentication by email';
    END IF;
END $$;

-- Index for phone lookup
CREATE INDEX IF NOT EXISTS idx_users_phone ON users(phone) WHERE phone IS NOT NULL;
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_users_phone') THEN
        COMMENT ON INDEX idx_users_phone IS 'Optimized index for user lookup by phone';
    END IF;
END $$;

-- ==================== Children Table ====================

-- Composite index for family's children with birthdate
CREATE INDEX IF NOT EXISTS idx_children_family_birthdate ON children(family_id, birth_date DESC);
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_children_family_birthdate') THEN
        COMMENT ON INDEX idx_children_family_birthdate IS 'Optimized for fetching family children ordered by age';
    END IF;
END $$;

-- ==================== Activities Table ====================

-- Index for activity type filtering
CREATE INDEX IF NOT EXISTS idx_activities_type_started_at ON activities(type, started_at DESC);
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_activities_type_started_at') THEN
        COMMENT ON INDEX idx_activities_type_started_at IS 'Optimized for activity type queries';
    END IF;
END $$;

-- ==================== Family Members Table ====================

-- Indexes already exist from previous migrations, just add comments
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_family_members_user_role') THEN
        COMMENT ON INDEX idx_family_members_user_role IS 'Optimized for user family lookup with role';
    END IF;
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_family_members_family') THEN
        COMMENT ON INDEX idx_family_members_family IS 'Optimized for family member queries';
    END IF;
END $$;

-- ==================== Refresh Tokens Table ====================

-- Indexes already exist from previous migrations, just add comments
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_refresh_tokens_expires') THEN
        COMMENT ON INDEX idx_refresh_tokens_expires IS 'Optimized for token expiration queries';
    END IF;
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_refresh_tokens_user_active') THEN
        COMMENT ON INDEX idx_refresh_tokens_user_active IS 'Optimized for user active token queries';
    END IF;
END $$;

-- ==================== Device Registry Table ====================

-- Index already exists from previous migrations, just add comment
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_device_registry_user_trusted') THEN
        COMMENT ON INDEX idx_device_registry_user_trusted IS 'Optimized for trusted device queries';
    END IF;
END $$;

-- ==================== Audit Log Table ====================

-- Composite index for user audit queries with timestamp
CREATE INDEX IF NOT EXISTS idx_audit_log_user_timestamp
  ON audit_log(user_id, created_at DESC)
  WHERE user_id IS NOT NULL;
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_audit_log_user_timestamp') THEN
        COMMENT ON INDEX idx_audit_log_user_timestamp IS 'Optimized for user audit log time-based queries';
    END IF;
END $$;

-- ==================== Photos Table (conditional - may not exist yet) ====================

-- Only create indexes if photos table exists
DO $$
BEGIN
    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'photos') THEN
        -- Indexes already exist from V008_create_photos.sql, just add comments
        IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_photos_child_created') THEN
            COMMENT ON INDEX idx_photos_child_created IS 'Optimized for child photo queries';
        END IF;
        IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_photos_activity') THEN
            COMMENT ON INDEX idx_photos_activity IS 'Optimized for activity photo queries';
        END IF;
        IF EXISTS (SELECT 1 FROM pg_indexes WHERE indexname = 'idx_photos_user') THEN
            COMMENT ON INDEX idx_photos_user IS 'Optimized for user photo queries';
        END IF;
    END IF;
END $$;

-- ==================== Performance Statistics ====================

-- Create a view for monitoring index usage
CREATE OR REPLACE VIEW v_index_usage AS
SELECT
  schemaname,
  relname as tablename,
  indexrelname as indexname,
  idx_scan as scans,
  idx_tup_read as tuples_read,
  idx_tup_fetch as tuples_fetched,
  pg_size_pretty(pg_relation_size(indexrelid)) as size
FROM pg_stat_user_indexes
ORDER BY idx_scan ASC;

COMMENT ON VIEW v_index_usage IS 'Monitor index usage for performance optimization';

-- Create a view for table statistics
CREATE OR REPLACE VIEW v_table_stats AS
SELECT
  schemaname,
  relname as tablename,
  seq_scan as sequential_scans,
  seq_tup_read as seq_tuples_read,
  idx_scan as index_scans,
  idx_tup_fetch as idx_tuples_fetched,
  n_tup_ins as inserts,
  n_tup_upd as updates,
  n_tup_del as deletes,
  n_live_tup as live_tuples,
  n_dead_tup as dead_tuples,
  pg_size_pretty(pg_total_relation_size(schemaname||'.'||relname)) as total_size
FROM pg_stat_user_tables
ORDER BY seq_scan DESC;

COMMENT ON VIEW v_table_stats IS 'Monitor table statistics for performance optimization';

-- ==================== Vacuum and Analyze ====================

-- Analyze tables to update statistics (only if they exist)
DO $$
BEGIN
    ANALYZE users;
    ANALYZE children;
    ANALYZE activities;
    ANALYZE family_members;
    ANALYZE families;
    ANALYZE refresh_tokens;
    ANALYZE device_registry;
    ANALYZE audit_log;

    -- Only analyze photos if it exists
    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'photos') THEN
        ANALYZE photos;
    END IF;
END $$;
