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

interface CancelProjectRequest {
  reason: string;
  description?: string;
  requestRefund?: boolean;
}

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?.id) {
      return NextResponse.json(
        { error: 'Unauthorized' },
        { status: 401 }
      );
    }

    const { projectId } = await params;
    const body: CancelProjectRequest = await req.json();
    const { reason, description, requestRefund = false } = body;

    if (!projectId) {
      return NextResponse.json(
        { error: 'Project ID is required' },
        { status: 400 }
      );
    }

    if (!reason) {
      return NextResponse.json(
        { error: 'Cancellation reason is required' },
        { status: 400 }
      );
    }

    try {
      // Verify user has access to this project and it's not already cancelled
      const project = await prisma.project.findFirst({
        where: {
          id: projectId,
          status: { not: 'CANCELLED' },
          clientId: session.user.id
        },
        include: {
          client: {
            select: {
              id: true,
              email: true,
              profile: {
                select: {
                  firstName: true,
                  lastName: true
                }
              }
            }
          },
          bids: {
            where: { status: 'ACCEPTED' },
            include: {
              freelancer: {
                select: {
                  id: true,
                  email: true,
                  profile: {
                    select: {
                      firstName: true,
                      lastName: true
                    }
                  }
                }
              }
            }
          }
        }
      });

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

      const userRole = 'client'; // Only clients can cancel projects
      const currentDate = new Date();

      // Calculate refund amount based on project progress and cancellation timing
      let refundAmount = null;
      let refundStatus = 'not_applicable';

      if (requestRefund && userRole === 'client') {
        // Simple refund calculation - in real app, this would be more complex
        const projectAge = currentDate.getTime() - new Date(project.createdAt).getTime();
        const daysOld = projectAge / (1000 * 60 * 60 * 24);
        
        if (daysOld <= 1) {
          refundAmount = project.budget; // 100% refund within 24 hours
        } else if (daysOld <= 7) {
          refundAmount = project.budget * 0.8; // 80% refund within a week
        } else {
          refundAmount = project.budget * 0.5; // 50% refund after a week
        }
        
        refundStatus = 'pending';
      }

      // Start transaction to ensure data consistency
      const result = await prisma.$transaction(async (tx) => {
        // Update project status to cancelled
        const updatedProject = await tx.project.update({
          where: { id: projectId },
          data: {
            status: 'CANCELLED',
            completedAt: currentDate
          }
        });

        // Update all bids to withdrawn status (since project is cancelled)
        await tx.bid.updateMany({
          where: { projectId: projectId },
          data: { status: 'WITHDRAWN' }
        });

        // If there's an accepted bid, create system message for the freelancer
        const acceptedBid = project.bids.find(bid => bid.status === 'ACCEPTED');
        if (acceptedBid) {
          await tx.message.create({
            data: {
              content: `⚠️ Project Cancelled\n\nThe client has cancelled the project "${project.title}". Reason: ${reason}`,
              messageType: 'system',
              projectId: projectId,
              bidId: acceptedBid.id,
              senderId: session.user.id,
              receiverId: acceptedBid.freelancerId,
              isRead: false
            }
          });
        }

        return { updatedProject };
      });

      const { updatedProject } = result;

      // Send enhanced notification to freelancer if there's an accepted bid
      const acceptedBid = project.bids.find(bid => bid.status === 'ACCEPTED');
      if (acceptedBid) {
        const clientName = session.user?.name || session.user?.email || 'Client';
        
        try {
          await NotificationService.notifyProjectCancelledByClient(
            acceptedBid.freelancer.id,
            clientName,
            project.title,
            projectId,
            reason,
            requestRefund
          );
        } catch (notificationError) {
          console.error('Failed to create cancellation notification:', notificationError);
        }
      }

      // Log user activity
      console.log(`Activity logged: Project cancelled by user ${session.user.id}: ${project.title}. Reason: ${reason}`);

      return NextResponse.json({
        success: true,
        message: 'Project cancelled successfully',
        data: {
          projectId: projectId,
          status: 'CANCELLED',
          cancelledAt: currentDate.toISOString(),
          reason: reason,
          refundRequested: requestRefund,
          refundAmount: refundAmount,
          refundStatus: refundStatus
        }
      });

    } catch (dbError: any) {
      console.error('Database error during project cancellation:', dbError);
      
      return NextResponse.json(
        { 
          error: 'Database operation failed',
          message: 'Unable to cancel 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 cancelling project:', error);
    
    return NextResponse.json(
      { 
        error: error instanceof Error ? error.message : 'Failed to cancel project',
        type: 'server_error'
      },
      { status: 500 }
    );
  }
}