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

interface SendProjectMessageRequest {
  content: string;
  messageType: 'text' | 'file' | 'milestone' | 'system';
  fileUrl?: string;
  fileName?: string;
  milestoneId?: 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: SendProjectMessageRequest = await req.json();
    const { content, messageType = 'text', fileUrl, fileName, milestoneId } = body;

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

    if (messageType === 'text' && (!content || content.trim().length === 0)) {
      return NextResponse.json(
        { error: 'Message content is required' },
        { status: 400 }
      );
    }

    if (messageType === 'file' && (!fileUrl || !fileName)) {
      return NextResponse.json(
        { error: 'File URL and filename are required for file messages' },
        { status: 400 }
      );
    }

    try {
      const { searchParams } = new URL(req.url);
      const bidId = searchParams.get('bidId');

      // Verify user has access to this project
      const project = await prisma.project.findFirst({
        where: {
          OR: [
            { id: projectId, clientId: session.user.email },
            { 
              id: projectId, 
              bids: {
                some: {
                  freelancerId: session.user.email
                }
              }
            }
          ]
        },
        include: {
          selectedBid: {
            include: {
              freelancer: {
                select: {
                  id: true,
                  email: true
                }
              }
            }
          },
          client: {
            select: {
              id: true,
              email: true,
              image: true,
              profile: {
                select: {
                  firstName: true,
                  lastName: true
                }
              }
            }
          },
          bids: {
            where: {
              freelancerId: session.user.email
            },
            select: {
              id: true,
              status: true,
              freelancer: {
                select: {
                  email: true
                }
              }
            }
          }
        }
      });

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

      // Determine which bid this message belongs to
      let targetBidId = bidId;
      let receiverId: string;

      if (!targetBidId) {
        if (session.user.email === project.clientId) {
          // Client sending message - use selected bid if available
          targetBidId = project.selectedBidId;
          if (project.selectedBid) {
            receiverId = project.selectedBid.freelancer.email;
          } else {
            return NextResponse.json(
              { error: 'No active conversation available' },
              { status: 400 }
            );
          }
        } else {
          // Freelancer sending message - use their own bid
          const userBid = project.bids.find(bid => bid.freelancer.email === session.user.email);
          if (!userBid) {
            return NextResponse.json(
              { error: 'No bid found for this user' },
              { status: 404 }
            );
          }
          targetBidId = userBid.id;
          receiverId = project.clientId;
        }
      } else {
        // Validate bidId access
        if (session.user.email === project.clientId) {
          // Client can send to selected bid only
          if (targetBidId !== project.selectedBidId) {
            return NextResponse.json(
              { error: 'Can only message selected freelancer' },
              { status: 403 }
            );
          }
          receiverId = project.selectedBid?.freelancer.email || '';
        } else {
          // Freelancer can only send to their own bid
          const userBid = project.bids.find(bid => bid.id === targetBidId);
          if (!userBid) {
            return NextResponse.json(
              { error: 'Access denied to this conversation' },
              { status: 403 }
            );
          }
          receiverId = project.clientId;
        }
      }

      // Check if chat is disabled (project cancelled or bid not selected)
      if (project.status === 'CANCELLED') {
        return NextResponse.json(
          { error: 'Cannot send messages to cancelled project' },
          { status: 400 }
        );
      }

      if (project.selectedBidId && project.selectedBidId !== targetBidId) {
        return NextResponse.json(
          { error: 'Chat disabled - project awarded to another freelancer' },
          { status: 403 }
        );
      }

      // Create the message
      const message = await prisma.message.create({
        data: {
          content: content?.trim() || '',
          senderId: session.user.email,
          receiverId: receiverId,
          projectId: projectId,
          bidId: targetBidId,
          messageType: messageType,
          attachments: fileUrl ? JSON.stringify([{ url: fileUrl, name: fileName }]) : null
        },
        include: {
          sender: {
            select: {
              id: true,
              email: true,
              image: true,
              profile: {
                select: {
                  firstName: true,
                  lastName: true
                }
              }
            }
          }
        }
      });

      // Update project's last activity
      await prisma.project.update({
        where: { id: projectId },
        data: { updatedAt: new Date() }
      });

      // Log user activity

      // Format response
      const senderName = `${message.sender.profile?.firstName || ''} ${message.sender.profile?.lastName || ''}`.trim() || 'Unknown User';
      const senderRole = session.user.email === project.clientId ? 'client' : 'freelancer';

      const responseData = {
        id: message.id,
        projectId: message.projectId,
        bidId: targetBidId,
        senderId: message.senderId,
        senderName: senderName,
        senderAvatar: message.sender.image || '/assets/image/default-avatar.png',
        senderRole: senderRole,
        content: message.content,
        messageType: message.messageType,
        fileUrl: fileUrl || null,
        fileName: fileName || null,
        timestamp: new Date(message.createdAt).toLocaleTimeString('en-US', { 
          hour: '2-digit', 
          minute: '2-digit' 
        }),
        isRead: message.isRead,
        createdAt: message.createdAt.toISOString()
      };

      // Send real-time notification via WebSocket
      try {
        const { wsBridge } = await import('@/lib/websocket-bridge');
        
        // Broadcast to receiver
        const sentToUser = wsBridge.sendToUser(receiverId, {
          type: 'new_message',
          message: responseData
        });
        
        // Broadcast to project/bid room
        const roomId = targetBidId ? `bid_${targetBidId}` : `project_${projectId}`;
        const sentToRoom = wsBridge.broadcastToRoom(roomId, {
          type: 'new_message',
          message: responseData
        });
        
      } catch (wsError) {
        // Continue without WebSocket - message was saved to DB
      }

      return NextResponse.json({
        success: true,
        data: responseData,
        message: 'Message sent successfully'
      });

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

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