-- Migration 021: Cleanup Migration Conflicts
-- This migration resolves conflicts and ensures schema consistency

-- =============================================
-- Schema Consistency Fixes
-- =============================================

-- Fix missing ID column in repository_directories (from migration 017)
DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'repository_directories' 
        AND column_name = 'id'
        AND table_schema = 'public'
    ) THEN
        ALTER TABLE repository_directories 
        ADD COLUMN id UUID PRIMARY KEY DEFAULT uuid_generate_v4();
        RAISE NOTICE 'Added missing id column to repository_directories';
    END IF;
END $$;

-- Ensure user_id column exists with consistent constraints
DO $$
BEGIN
    -- Check if user_id exists in all_repositories
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'all_repositories' 
        AND column_name = 'user_id'
        AND table_schema = 'public'
    ) THEN
        ALTER TABLE all_repositories 
        ADD COLUMN user_id UUID REFERENCES users(id) ON DELETE SET NULL;
        RAISE NOTICE 'Added user_id column to all_repositories';
    END IF;
    
    -- Ensure index exists
    IF NOT EXISTS (
        SELECT 1 FROM pg_indexes 
        WHERE tablename = 'all_repositories' 
        AND indexname = 'idx_all_repositories_user_id'
    ) THEN
        CREATE INDEX idx_all_repositories_user_id ON all_repositories(user_id);
        RAISE NOTICE 'Created index on all_repositories.user_id';
    END IF;
END $$;

-- Fix template_id references that may not exist
DO $$
BEGIN
    -- Check if templates table exists
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.tables 
        WHERE table_name = 'templates' 
        AND table_schema = 'public'
    ) THEN
        -- Remove foreign key constraint if templates table doesn't exist
        IF EXISTS (
            SELECT 1 FROM information_schema.table_constraints 
            WHERE table_name = 'all_repositories' 
            AND constraint_type = 'FOREIGN KEY'
            AND constraint_name LIKE '%template_id%'
        ) THEN
            -- Find and drop the constraint
            DECLARE
                constraint_name_var TEXT;
            BEGIN
                SELECT constraint_name INTO constraint_name_var
                FROM information_schema.table_constraints 
                WHERE table_name = 'all_repositories' 
                AND constraint_type = 'FOREIGN KEY'
                AND constraint_name LIKE '%template_id%'
                LIMIT 1;
                
                IF constraint_name_var IS NOT NULL THEN
                    EXECUTE 'ALTER TABLE all_repositories DROP CONSTRAINT ' || constraint_name_var;
                    RAISE NOTICE 'Dropped foreign key constraint % (templates table does not exist)', constraint_name_var;
                END IF;
            END;
        END IF;
    END IF;
END $$;

-- =============================================
-- Index Optimization
-- =============================================

-- Ensure all critical indexes exist
CREATE INDEX IF NOT EXISTS idx_all_repositories_provider_name ON all_repositories(provider_name);
CREATE INDEX IF NOT EXISTS idx_all_repositories_owner_name ON all_repositories(owner_name);
CREATE INDEX IF NOT EXISTS idx_all_repositories_sync_status ON all_repositories(sync_status);
CREATE INDEX IF NOT EXISTS idx_all_repositories_created_at ON all_repositories(created_at);

-- Repository storage indexes
CREATE INDEX IF NOT EXISTS idx_repository_storage_status ON repository_storage(storage_status);
-- Note: The repository_files table has been optimized in migration 003_optimize_repository_files.sql
-- The following indexes are already created in the optimized table structure:
-- - idx_repo_files_files_gin (GIN index on files JSONB column)
-- - idx_repo_files_filename (GIN index on files->>'filename')
-- - idx_repo_files_extension (GIN index on files->>'file_extension')
-- - idx_repo_files_is_binary (GIN index on files->>'is_binary')

-- Webhook indexes for performance
CREATE INDEX IF NOT EXISTS idx_github_webhooks_event_type ON github_webhooks(event_type);
CREATE INDEX IF NOT EXISTS idx_github_webhooks_created_at ON github_webhooks(created_at);

-- =============================================
-- Data Integrity Checks
-- =============================================

-- Check for orphaned records and report
DO $$
DECLARE
    orphaned_count INTEGER;
BEGIN
    -- Check for repositories without valid storage references
    SELECT COUNT(*) INTO orphaned_count
    FROM all_repositories ar
    LEFT JOIN repository_storage rs ON ar.id = rs.repository_id
    WHERE rs.id IS NULL;
    
    IF orphaned_count > 0 THEN
        RAISE NOTICE 'Found % repositories without storage records', orphaned_count;
    END IF;
    
    -- Check for files without valid directory references
    SELECT COUNT(*) INTO orphaned_count
    FROM repository_files rf
    LEFT JOIN repository_directories rd ON rf.directory_id = rd.id
    WHERE rf.directory_id IS NOT NULL AND rd.id IS NULL;
    
    IF orphaned_count > 0 THEN
        RAISE NOTICE 'Found % files with invalid directory references', orphaned_count;
    END IF;
END $$;

-- =============================================
-- Performance Optimizations
-- =============================================

-- Update table statistics for better query planning
ANALYZE all_repositories;
ANALYZE repository_storage;
ANALYZE repository_files;
ANALYZE repository_directories;
ANALYZE github_webhooks;

-- =============================================
-- Migration Validation
-- =============================================

-- Validate critical tables exist
DO $$
DECLARE
    missing_tables TEXT[] := ARRAY[]::TEXT[];
BEGIN
    -- Check for required tables
    IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'all_repositories') THEN
        missing_tables := array_append(missing_tables, 'all_repositories');
    END IF;
    
    IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'repository_storage') THEN
        missing_tables := array_append(missing_tables, 'repository_storage');
    END IF;
    
    IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'github_user_tokens') THEN
        missing_tables := array_append(missing_tables, 'github_user_tokens');
    END IF;
    
    IF array_length(missing_tables, 1) > 0 THEN
        RAISE EXCEPTION 'Critical tables missing: %', array_to_string(missing_tables, ', ');
    ELSE
        RAISE NOTICE '✅ All critical tables present';
    END IF;
END $$;

-- Validate critical columns exist
DO $$
DECLARE
    missing_columns TEXT[] := ARRAY[]::TEXT[];
BEGIN
    -- Check for user_id in all_repositories
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'all_repositories' AND column_name = 'user_id'
    ) THEN
        missing_columns := array_append(missing_columns, 'all_repositories.user_id');
    END IF;
    
    -- Check for provider_name in all_repositories
    IF NOT EXISTS (
        SELECT 1 FROM information_schema.columns 
        WHERE table_name = 'all_repositories' AND column_name = 'provider_name'
    ) THEN
        missing_columns := array_append(missing_columns, 'all_repositories.provider_name');
    END IF;
    
    IF array_length(missing_columns, 1) > 0 THEN
        RAISE EXCEPTION 'Critical columns missing: %', array_to_string(missing_columns, ', ');
    ELSE
        RAISE NOTICE '✅ All critical columns present';
    END IF;
END $$;

-- Final completion notice
DO $$
BEGIN
    RAISE NOTICE '🎉 Migration 021 completed - Schema conflicts resolved';
END $$;
