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

interface AwardProjectRequest {
  bidId: string;
  message?: string;
}

export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ projectId: string }> }
) {
  try {
    if (!prisma) {
      return NextResponse.json(
        { error: 'Database connection not available' },
        { status: 503 }
      );
    }

    const session = await getServerSession(authOptions);
    
    if (!session?.user?.email) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    const { projectId } = await params;
    const body: AwardProjectRequest = await req.json();
    const { bidId, message } = body;

    if (!projectId) {
      return NextResponse.json(
        { 
          error: 'Validation failed',
          message: 'Project ID is required to award the project.' 
        },
        { status: 400 }
      );
    }

    if (!bidId) {
      return NextResponse.json(
        { 
          error: 'Validation failed',
          message: 'Please select a bid to award the project to.' 
        },
        { status: 400 }
      );
    }

    try {
      // Verify user owns this project and it's not already awarded
      const project = await prisma.project.findFirst({
        where: {
          id: projectId,
          clientId: session.user.email,
          status: 'OPEN'
        },
        include: {
          category: true,
          client: {
            select: {
              profile: {
                select: {
                  firstName: true,
                  lastName: true
                }
              }
            }
          }
        }
      });

      if (!project) {
        return NextResponse.json(
          { error: 'Project not found, already awarded, or access denied' },
          { status: 404 }
        );
      }

      // Verify the bid exists and belongs to this project
      const selectedBid = await prisma.bid.findFirst({
        where: {
          id: bidId,
          projectId: projectId,
          status: 'PENDING'
        },
        include: {
          freelancer: {
            select: {
              id: true,
              email: true,
              profile: {
                select: {
                  firstName: true,
                  lastName: true
                }
              }
            }
          }
        }
      });

      if (!selectedBid) {
        return NextResponse.json(
          { error: 'Bid not found or not available for award' },
          { status: 404 }
        );
      }

      const currentDate = new Date();
      
      // Start transaction to ensure data consistency
      const result = await prisma.$transaction(async (tx) => {
        // Update project with selected bid and change status
        const updatedProject = await tx.project.update({
          where: { id: projectId },
          data: {
            selectedBidId: bidId,
            status: 'IN_PROGRESS',
            updatedAt: currentDate
          }
        });

        // Update the selected bid to ACCEPTED
        await tx.bid.update({
          where: { id: bidId },
          data: {
            status: 'ACCEPTED',
            updatedAt: currentDate
          }
        });

        // Reject all other bids for this project
        await tx.bid.updateMany({
          where: {
            projectId: projectId,
            id: { not: bidId },
            status: 'PENDING'
          },
          data: {
            status: 'REJECTED',
            updatedAt: currentDate
          }
        });

        // Disable chat for non-awarded freelancers
        await tx.message.updateMany({
          where: {
            projectId: projectId,
            bidId: { not: bidId }
          },
          data: {
            isDisabled: true,
            updatedAt: currentDate
          }
        });

        // Send award message to the selected freelancer
        if (message) {
          await tx.message.create({
            data: {
              content: message,
              senderId: session.user.email!,
              receiverId: selectedBid.freelancer.email,
              projectId: projectId,
              bidId: bidId,
              messageType: 'text'
            }
          });
        }

        // Send system message about project award
        await tx.message.create({
          data: {
            content: `Project awarded! You have been selected to work on "${project.title}". Congratulations!`,
            senderId: 'system',
            receiverId: selectedBid.freelancer.email,
            projectId: projectId,
            bidId: bidId,
            messageType: 'system'
          }
        });

        return { updatedProject, selectedBid };
      });

      // Send notifications to all bidders
      try {
        // Get all bids for this project
        const allBids = await prisma.bid.findMany({
          where: { projectId: projectId },
          include: {
            freelancer: {
              select: {
                email: true,
                profile: {
                  select: {
                    firstName: true,
                    lastName: true
                  }
                }
              }
            }
          }
        });

        // Send notifications and emails
        for (const bid of allBids) {
          if (bid.id === bidId) {
            // Winner notification
            await prisma.notification.create({
              data: {
                userId: bid.freelancer.email,
                type: 'project_awarded',
                title: 'Project Awarded!',
                message: `Congratulations! You've been selected for the project "${project.title}"`,
                data: JSON.stringify({
                  projectId: projectId,
                  bidId: bid.id,
                  amount: bid.amount
                })
              }
            });

            // Send winner email
            try {
              await EmailService.sendProjectAwardedEmail(bid.freelancer.email, {
                freelancerName: `${bid.freelancer.profile?.firstName || ''} ${bid.freelancer.profile?.lastName || ''}`.trim() || 'Freelancer',
                projectTitle: project.title,
                clientName: `${project.client.profile?.firstName || ''} ${project.client.profile?.lastName || ''}`.trim() || 'Client',
                bidAmount: bid.amount,
                projectUrl: `${process.env.NEXT_PUBLIC_APP_URL || 'http://46.202.162.227:3003'}/freelancer/projects/ongoing/${projectId}`
              });
            } catch (emailError) {
              console.error('Failed to send award email:', emailError);
            }
          } else {
            // Non-winner notification
            await prisma.notification.create({
              data: {
                userId: bid.freelancer.email,
                type: 'bid_rejected',
                title: 'Bid Not Selected',
                message: `Your bid for "${project.title}" was not selected. Thank you for your interest.`,
                data: JSON.stringify({
                  projectId: projectId,
                  bidId: bid.id
                })
              }
            });
          }
        }
      } catch (notificationError) {
        console.error('Failed to send notifications:', notificationError);
      }

      return NextResponse.json({
        success: true,
        message: 'Project awarded successfully',
        data: {
          projectId: projectId,
          selectedBidId: bidId,
          freelancerId: selectedBid.freelancer.email,
          freelancerName: `${selectedBid.freelancer.profile?.firstName || ''} ${selectedBid.freelancer.profile?.lastName || ''}`.trim(),
          awardedAt: currentDate.toISOString(),
          projectStatus: 'IN_PROGRESS'
        }
      });

    } catch (dbError: any) {
      console.error('Database error during project award:', dbError);
      
      return NextResponse.json(
        { 
          error: 'Database operation failed',
          message: 'Unable to award project due to a database error. Please try again later.',
          details: process.env.NODE_ENV === 'development' ? dbError.message : undefined
        },
        { status: 500 }
      );
    }

  } catch (error) {
    console.error('Error awarding project:', error);
    
    return NextResponse.json(
      { 
        error: error instanceof Error ? error.message : 'Failed to award project',
        type: 'server_error'
      },
      { status: 500 }
    );
  }
}