import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@/app/api/auth/[...nextauth]/route';
import { prismaAuth } from '@/lib/db';

// In-memory cache for report statuses
// Key: `${userId}:${photoId}`, Value: { data, expiresAt }
interface CacheEntry {
  data: {
    reported: boolean;
    status?: string;
    reportedAt?: Date;
  };
  expiresAt: number;
}

const reportStatusCache = new Map<string, CacheEntry>();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

// Helper function to get cache key
function getCacheKey(userId: number, photoId: number): string {
  return `${userId}:${photoId}`;
}

// Helper function to get cached report status
function getCachedStatus(userId: number, photoId: number): CacheEntry['data'] | null {
  const key = getCacheKey(userId, photoId);
  const entry = reportStatusCache.get(key);
  
  if (!entry) {
    return null;
  }
  
  // Check if cache entry has expired
  if (Date.now() > entry.expiresAt) {
    reportStatusCache.delete(key);
    return null;
  }
  
  return entry.data;
}

// Helper function to set cache
function setCachedStatus(
  userId: number,
  photoId: number,
  data: CacheEntry['data']
): void {
  const key = getCacheKey(userId, photoId);
  reportStatusCache.set(key, {
    data,
    expiresAt: Date.now() + CACHE_TTL,
  });
}

// Helper function to fetch report status from database
async function fetchReportStatusFromDB(
  userId: number,
  photoId: number
): Promise<CacheEntry['data']> {
  const existingReport = await prismaAuth.inappropriatePhotoReport.findUnique({
    where: {
      uq_photo_user_report: {
        photoId,
        userId,
      },
    },
    select: {
      id: true,
      status: true,
      reportedAt: true,
    },
  });

  const result: CacheEntry['data'] = existingReport
    ? {
        reported: true,
        status: existingReport.status,
        reportedAt: existingReport.reportedAt,
      }
    : {
        reported: false,
      };

  // Cache the result
  setCachedStatus(userId, photoId, result);
  
  return result;
}

export async function POST(request: NextRequest) {
  try {
    // Check authentication
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json(
        { error: 'Authentication required' },
        { status: 401 }
      );
    }

    const userId = parseInt(session.user.id, 10);
    if (isNaN(userId)) {
      return NextResponse.json(
        { error: 'Invalid user ID' },
        { status: 400 }
      );
    }

    // Parse request body
    const body = await request.json();
    const { photoIds } = body;

    if (!Array.isArray(photoIds) || photoIds.length === 0) {
      return NextResponse.json(
        { error: 'photoIds must be a non-empty array' },
        { status: 400 }
      );
    }

    // Validate photo IDs are numbers
    const validPhotoIds = photoIds
      .map((id) => parseInt(String(id), 10))
      .filter((id) => !isNaN(id) && id > 0);

    if (validPhotoIds.length === 0) {
      return NextResponse.json(
        { error: 'No valid photo IDs provided' },
        { status: 400 }
      );
    }

    // Limit batch size to prevent abuse
    const MAX_BATCH_SIZE = 100;
    const photoIdsToCheck = validPhotoIds.slice(0, MAX_BATCH_SIZE);

    // Check cache first for all photos
    const results: Record<number, CacheEntry['data']> = {};
    const uncachedPhotoIds: number[] = [];

    for (const photoId of photoIdsToCheck) {
      const cached = getCachedStatus(userId, photoId);
      if (cached !== null) {
        results[photoId] = cached;
      } else {
        uncachedPhotoIds.push(photoId);
      }
    }

    // Fetch uncached report statuses from database in a single query
    if (uncachedPhotoIds.length > 0) {
      const reports = await prismaAuth.inappropriatePhotoReport.findMany({
        where: {
          userId,
          photoId: { in: uncachedPhotoIds },
        },
        select: {
          photoId: true,
          status: true,
          reportedAt: true,
        },
      });

      // Create a map of photoId -> report status
      const reportMap = new Map<number, { status: string; reportedAt: Date }>();
      for (const report of reports) {
        reportMap.set(report.photoId, {
          status: report.status,
          reportedAt: report.reportedAt,
        });
      }

      // Build results for uncached photos
      for (const photoId of uncachedPhotoIds) {
        const report = reportMap.get(photoId);
        const result: CacheEntry['data'] = report
          ? {
              reported: true,
              status: report.status,
              reportedAt: report.reportedAt,
            }
          : {
              reported: false,
            };

        results[photoId] = result;
        // Cache the result
        setCachedStatus(userId, photoId, result);
      }
    }

    return NextResponse.json({ results });
  } catch (error: any) {
    console.error('Error fetching batch report statuses:', error);
    return NextResponse.json(
      { error: 'Failed to fetch report statuses', details: error.message },
      { status: 500 }
    );
  }
}







