
import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/db';

export async function GET(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user?.id) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const searchParams = request.nextUrl.searchParams;
    const period = searchParams.get('period') || new Date().toISOString().slice(0, 7);
    const metric = searchParams.get('metric') || 'revenue'; // revenue, rating, contracts
    const limit = parseInt(searchParams.get('limit') || '10');

    // Fetch all contractor performance for the period
    const performances = await prisma.contractorPerformance.findMany({
      where: { period },
      include: {
        user: {
          select: {
            id: true,
            name: true,
            email: true,
            image: true,
            partnerProfile: {
              select: {
                companyName: true,
                services: true,
                isVerified: true,
              },
            },
          },
        },
      },
      orderBy:
        metric === 'revenue'
          ? { revenue: 'desc' }
          : metric === 'rating'
          ? { averageRating: 'desc' }
          : { contractsWon: 'desc' },
      take: limit,
    });

    // Get reviews count for each contractor
    const contractorIds = performances.map((p: any) => p.userId);
    const reviewCounts = await prisma.contractorReview.groupBy({
      by: ['contractorId'],
      where: {
        contractorId: { in: contractorIds },
        isPublished: true,
      },
      _count: true,
    });

    const reviewCountMap = Object.fromEntries(
      reviewCounts.map((r: any) => [r.contractorId, r._count])
    );

    // Get badges for each contractor
    const badges = await prisma.contractorBadge.findMany({
      where: {
        contractorId: { in: contractorIds },
        isActive: true,
        isVerified: true,
      },
    });

    const badgesByContractor = badges.reduce((acc: Record<string, any[]>, badge: any) => {
      if (!acc[badge.contractorId]) acc[badge.contractorId] = [];
      acc[badge.contractorId].push(badge);
      return acc;
    }, {} as Record<string, any[]>);

    // Calculate response time metrics
    const responseMetrics = await calculateResponseMetrics(contractorIds);

    // Build leaderboard
    const leaderboard = performances.map((perf: any, index: number) => ({
      rank: index + 1,
      contractorId: perf.userId,
      contractorName: perf.user.name || perf.user.partnerProfile?.companyName,
      companyName: perf.user.partnerProfile?.companyName,
      isVerified: perf.user.partnerProfile?.isVerified,
      services: perf.user.partnerProfile?.services || [],
      
      // Performance metrics
      leadsAssigned: perf.leadsAssigned,
      quotesSubmitted: perf.quotesSubmitted,
      contractsWon: perf.contractsWon,
      revenue: perf.revenue,
      averageRating: perf.averageRating,
      completionRate: perf.completionRate,
      customerSatisfaction: perf.customerSatisfaction,
      
      // Additional metrics
      reviewCount: reviewCountMap[perf.userId] || 0,
      badges: badgesByContractor[perf.userId] || [],
      averageResponseTime: responseMetrics[perf.userId]?.avgResponseTime || null,
      
      // Conversion metrics
      conversionRate: perf.quotesSubmitted > 0
        ? ((perf.contractsWon / perf.quotesSubmitted) * 100).toFixed(1)
        : '0',
    }));

    // Calculate overall stats
    const totalRevenue = performances.reduce((sum: number, p: any) => sum + p.revenue, 0);
    const avgRating = performances.length > 0
      ? performances.reduce((sum: number, p: any) => sum + p.averageRating, 0) / performances.length
      : 0;

    return NextResponse.json({
      leaderboard,
      period,
      metric,
      stats: {
        totalContractors: performances.length,
        totalRevenue,
        averageRating: avgRating.toFixed(2),
      },
    });
  } catch (error) {
    console.error('Error fetching leaderboard:', error);
    return NextResponse.json(
      { error: 'Failed to fetch leaderboard' },
      { status: 500 }
    );
  }
}

// Helper function to calculate response time metrics
async function calculateResponseMetrics(contractorIds: string[]) {
  // This would calculate average response time from leads to first quote
  // For now, return placeholder data
  const metrics: Record<string, { avgResponseTime: number }> = {};
  
  for (const id of contractorIds) {
    // TODO: Implement actual response time calculation
    metrics[id] = {
      avgResponseTime: Math.floor(Math.random() * 24) + 1, // Placeholder: 1-24 hours
    };
  }
  
  return metrics;
}
