import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

async function validateDatabaseIntegrity() {
  console.log('🔍 Running comprehensive database integrity check...');

  try {
    // 1. Check Video table integrity
    console.log('\n📹 Checking Video table...');
    const videos = await prisma.video.findMany({
      include: {
        playlist: true,
        uploader: true,
        _count: {
          select: {
            comments: true,
            likes: true,
            progress: true,
            unlocks: true,
            watchSegments: true,
            videoCourses: true
          }
        }
      }
    });
    console.log(`✅ Found ${videos.length} videos`);

    // 2. Check for videos with missing playlists
    const videosWithMissingPlaylists = videos.filter(v => !v.playlist);
    if (videosWithMissingPlaylists.length > 0) {
      console.log(`⚠️  Found ${videosWithMissingPlaylists.length} videos with missing playlists:`);
      videosWithMissingPlaylists.forEach(v => {
        console.log(`   - Video ID: ${v.id}, Title: "${v.title}", Playlist ID: ${v.playlistId}`);
      });
    }

    // 3. Check for playlists with no videos
    console.log('\n📋 Checking Playlist table...');
    const playlists = await prisma.playlist.findMany({
      include: {
        videos: true,
        course: true,
        _count: {
          select: {
            videos: true
          }
        }
      }
    });
    console.log(`✅ Found ${playlists.length} playlists`);

    const emptyPlaylists = playlists.filter(p => p.videos.length === 0);
    if (emptyPlaylists.length > 0) {
      console.log(`⚠️  Found ${emptyPlaylists.length} empty playlists:`);
      emptyPlaylists.forEach(p => {
        console.log(`   - Playlist ID: ${p.id}, Title: "${p.title}", Course: ${p.course?.title || 'Unknown'}`);
      });
    }

    // 4. Check VideoProgress integrity
    console.log('\n📊 Checking VideoProgress table...');
    const progressCount = await prisma.videoProgress.count();
    console.log(`✅ Found ${progressCount} progress records`);

    // Check for progress records with invalid video references
    const invalidProgress = await prisma.$queryRaw`
      SELECT vp.id, vp."videoId", vp."userId"
      FROM "VideoProgress" vp
      LEFT JOIN "Video" v ON vp."videoId" = v.id
      WHERE v.id IS NULL
    ` as Array<{id: string, videoId: string, userId: string}>;

    if (invalidProgress.length > 0) {
      console.log(`❌ Found ${invalidProgress.length} progress records with invalid video references:`);
      invalidProgress.forEach(p => {
        console.log(`   - Progress ID: ${p.id}, Video ID: ${p.videoId}, User ID: ${p.userId}`);
      });
    }

    // 5. Check VideoWatchSegment integrity
    console.log('\n⏱️  Checking VideoWatchSegment table...');
    const segmentsCount = await prisma.videoWatchSegment.count();
    console.log(`✅ Found ${segmentsCount} watch segments`);

    // Check for segments with invalid video references
    const invalidSegments = await prisma.$queryRaw`
      SELECT vws.id, vws."videoId", vws."userId"
      FROM "VideoWatchSegment" vws
      LEFT JOIN "Video" v ON vws."videoId" = v.id
      WHERE v.id IS NULL
    ` as Array<{id: string, videoId: string, userId: string}>;

    if (invalidSegments.length > 0) {
      console.log(`❌ Found ${invalidSegments.length} watch segments with invalid video references:`);
      invalidSegments.forEach(s => {
        console.log(`   - Segment ID: ${s.id}, Video ID: ${s.videoId}, User ID: ${s.userId}`);
      });
    }

    // 6. Check for duplicate video indexes within playlists
    console.log('\n🔄 Checking for duplicate video indexes...');
    for (const playlist of playlists) {
      if (playlist.videos.length > 0) {
        const indexes = playlist.videos.map(v => v.index);
        const uniqueIndexes = [...new Set(indexes)];
        if (indexes.length !== uniqueIndexes.length) {
          console.log(`⚠️  Playlist "${playlist.title}" has duplicate video indexes:`);
          const duplicates = indexes.filter((item, index) => indexes.indexOf(item) !== index);
          console.log(`   - Duplicate indexes: ${duplicates.join(', ')}`);
        }
      }
    }

    // 7. Check Enrollment integrity
    console.log('\n📚 Checking Enrollment table...');
    const enrollments = await prisma.enrollment.findMany({
      include: {
        user: true,
        course: true
      }
    });
    console.log(`✅ Found ${enrollments.length} enrollments`);

    const enrollmentsWithMissingUser = enrollments.filter(e => !e.user);
    const enrollmentsWithMissingCourse = enrollments.filter(e => !e.course);
    
    if (enrollmentsWithMissingUser.length > 0) {
      console.log(`❌ Found ${enrollmentsWithMissingUser.length} enrollments with missing users`);
    }
    if (enrollmentsWithMissingCourse.length > 0) {
      console.log(`❌ Found ${enrollmentsWithMissingCourse.length} enrollments with missing courses`);
    }

    // 8. Summary
    console.log('\n📋 Database Integrity Summary:');
    console.log(`   Videos: ${videos.length}`);
    console.log(`   Playlists: ${playlists.length} (${emptyPlaylists.length} empty)`);
    console.log(`   Progress Records: ${progressCount}`);
    console.log(`   Watch Segments: ${segmentsCount}`);
    console.log(`   Enrollments: ${enrollments.length}`);
    
    const hasIssues = videosWithMissingPlaylists.length > 0 || 
                     invalidProgress.length > 0 ||
                     invalidSegments.length > 0 ||
                     enrollmentsWithMissingUser.length > 0 ||
                     enrollmentsWithMissingCourse.length > 0;
    
    if (!hasIssues) {
      console.log('✨ All integrity checks passed! Database appears healthy.');
    } else {
      console.log('⚠️  Some integrity issues found. See details above.');
    }

  } catch (error) {
    console.error('❌ Error during integrity check:', error);
  } finally {
    await prisma.$disconnect();
  }
}

// Run the integrity check
validateDatabaseIntegrity()
  .then(() => {
    console.log('🔧 Database integrity check completed');
    process.exit(0);
  })
  .catch((error) => {
    console.error('💥 Integrity check failed:', error);
    process.exit(1);
  });