import { Suspense } from 'react';
import { prisma } from '@/lib/db';
import { HomePageContent } from './HomePageContent';
import { Photo } from '@prisma/client';
import { serializePhotos, serializePeople, serializeTags } from '@/lib/serialize';

async function getAllPeople() {
  try {
    return await prisma.person.findMany({
      select: {
        id: true,
        first_name: true,
        last_name: true,
        middle_name: true,
        maiden_name: true,
        date_of_birth: true,
        created_date: true,
      },
      orderBy: [
        { first_name: 'asc' },
        { last_name: 'asc' },
      ],
    });
  } catch (error: any) {
    // Handle corrupted data errors (P2023)
    if (error?.code === 'P2023' || error?.message?.includes('Conversion failed')) {
      console.warn('Corrupted person data detected, attempting fallback query');
      try {
        // Try with minimal fields first
        return await prisma.person.findMany({
          select: {
            id: true,
            first_name: true,
            last_name: true,
            // Exclude potentially corrupted optional fields
          },
          orderBy: [
            { first_name: 'asc' },
            { last_name: 'asc' },
          ],
        });
      } catch (fallbackError: any) {
        console.error('Fallback person query also failed:', fallbackError);
        // Return empty array as last resort to prevent page crash
        return [];
      }
    }
    // Re-throw if it's a different error
    throw error;
  }
}

async function getAllTags() {
  try {
    return await prisma.tag.findMany({
      select: {
        id: true,
        tag_name: true,
        created_date: true,
      },
      orderBy: { tag_name: 'asc' },
    });
  } catch (error: any) {
    // Handle corrupted data errors (P2023)
    if (error?.code === 'P2023' || error?.message?.includes('Conversion failed')) {
      console.warn('Corrupted tag data detected, attempting fallback query');
      try {
        // Try with minimal fields
        return await prisma.tag.findMany({
          select: {
            id: true,
            tag_name: true,
            // Exclude potentially corrupted date field
          },
          orderBy: { tag_name: 'asc' },
        });
      } catch (fallbackError: any) {
        console.error('Fallback tag query also failed:', fallbackError);
        // Return empty array as last resort to prevent page crash
        return [];
      }
    }
    // Re-throw if it's a different error
    throw error;
  }
}

export default async function HomePage() {
  // Fetch photos from database
  // Note: Make sure DATABASE_URL is set in .env file
  let photos: any[] = []; // Using any to handle select-based query return type
  let error: string | null = null;

  try {
    // Fetch first page of photos (30 photos) for initial load
    // Infinite scroll will load more as user scrolls
    // Try to load with date fields first, fallback if corrupted data exists
    let photosBase;
    try {
      // Use raw query to read dates as strings and convert manually to avoid Prisma conversion issues
      const photosRaw = await prisma.$queryRaw<Array<{
        id: number;
        path: string;
        filename: string;
        date_added: string;
        date_taken: string | null;
        processed: boolean;
        media_type: string | null;
      }>>`
        SELECT 
          id, 
          path, 
          filename, 
          date_added, 
          date_taken, 
          processed, 
          media_type
        FROM photos
        WHERE processed = true
        ORDER BY date_taken DESC, id DESC
        LIMIT 30
      `;
      
      photosBase = photosRaw.map(photo => ({
        id: photo.id,
        path: photo.path,
        filename: photo.filename,
        date_added: new Date(photo.date_added),
        date_taken: photo.date_taken ? new Date(photo.date_taken) : null,
        processed: photo.processed,
        media_type: photo.media_type,
      }));
    } catch (dateError: any) {
      // If date fields are corrupted, load without them and use fallback values
      // Check for P2023 error code or various date conversion error messages
      const isDateError = dateError?.code === 'P2023' || 
                         dateError?.message?.includes('Conversion failed') ||
                         dateError?.message?.includes('Inconsistent column data') ||
                         dateError?.message?.includes('Could not convert value');
      
      if (isDateError) {
        console.warn('Corrupted date data detected, loading photos without date fields');
        photosBase = await prisma.photo.findMany({
          where: { processed: true },
          select: {
            id: true,
            path: true,
            filename: true,
            processed: true,
            media_type: true,
            // Exclude date fields due to corruption
          },
          orderBy: { id: 'desc' },
          take: 30,
        });
        // Add fallback date values
        photosBase = photosBase.map(photo => ({
          ...photo,
          date_added: new Date(),
          date_taken: null,
        }));
      } else {
        throw dateError;
      }
    }

    // If base query works, load faces separately
    const photoIds = photosBase.map(p => p.id);
    const faces = await prisma.face.findMany({
      where: { photo_id: { in: photoIds } },
      select: {
        id: true,
        photo_id: true,
        person_id: true,
        location: true,
        confidence: true,
        quality_score: true,
        is_primary_encoding: true,
        detector_backend: true,
        model_name: true,
        face_confidence: true,
        exif_orientation: true,
        pose_mode: true,
        yaw_angle: true,
        pitch_angle: true,
        roll_angle: true,
        landmarks: true,
        identified_by_user_id: true,
        excluded: true,
        Person: {
          select: {
            id: true,
            first_name: true,
            last_name: true,
            middle_name: true,
            maiden_name: true,
            date_of_birth: true,
            created_date: true,
          },
        },
        // Exclude encoding field (Bytes) to avoid P2023 conversion errors
      },
    });

    // Combine the data manually
    photos = photosBase.map(photo => ({
      ...photo,
      Face: faces.filter(face => face.photo_id === photo.id),
    })) as any;
  } catch (err) {
    error = err instanceof Error ? err.message : 'Failed to load photos';
    console.error('Error loading photos:', err);
  }

  // Fetch people and tags for search
  const [people, tags] = await Promise.all([
    getAllPeople(),
    getAllTags(),
  ]);

  return (
    <main className="w-full px-4 py-8">

      {error ? (
        <div className="rounded-lg bg-red-50 p-4 text-red-800 dark:bg-red-900/20 dark:text-red-200">
          <p className="font-semibold">Error loading photos</p>
          <p className="text-sm">{error}</p>
          <p className="mt-2 text-xs">
            Make sure DATABASE_URL is configured in your .env file
          </p>
        </div>
      ) : (
        <Suspense fallback={
          <div className="flex items-center justify-center py-12">
            <div className="text-center">
              <p className="text-gray-600 dark:text-gray-400">Loading...</p>
            </div>
          </div>
        }>
          <HomePageContent initialPhotos={serializePhotos(photos)} people={serializePeople(people)} tags={serializeTags(tags)} />
        </Suspense>
      )}
    </main>
  );
}
