
import { NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/db';
import { uploadFile } from '@/lib/s3';
import { sendEmail, getCustomerConfirmationEmail, getCrmNotificationEmail } from '@/lib/email';

export async function POST(request: Request) {
  try {
    // Check if request is multipart form data
    const contentType = request.headers.get('content-type');
    const isFormData = contentType?.includes('multipart/form-data');

    let data: any;
    let uploadedFilePaths: string[] = [];

    if (isFormData) {
      // Handle FormData for file uploads
      const formData = await request.formData();
      
      // Extract form fields
      const name = formData.get('name') as string;
      const nameParts = name?.split(' ') || ['', ''];
      const firstName = nameParts[0] || '';
      const lastName = nameParts.slice(1).join(' ') || '';
      
      data = {
        firstName,
        lastName,
        email: formData.get('email') as string,
        phone: formData.get('phone') as string,
        address: formData.get('address') as string,
        latitude: formData.get('latitude') ? parseFloat(formData.get('latitude') as string) : null,
        longitude: formData.get('longitude') ? parseFloat(formData.get('longitude') as string) : null,
        city: formData.get('city') as string || 'Johannesburg',
        state: formData.get('state') as string || 'Gauteng',
        zipCode: formData.get('zipCode') as string || '2000',
        source: formData.get('source') as string || 'WEB',
        status: formData.get('status') as string || 'NEW',
        services: [formData.get('serviceType') as string].filter(Boolean),
        description: formData.get('description') as string || null,
        budget: formData.get('budget') as string || null,
        timeline: formData.get('timeline') as string || null,
        priority: formData.get('priority') as string || 'HIGH',
        assignedToId: formData.get('assignedToId') as string || null,
        partnerId: formData.get('partnerId') as string || null,
      };

      // Handle file uploads to S3
      const files = formData.getAll('files') as File[];
      for (const file of files) {
        if (file && file.size > 0) {
          const buffer = Buffer.from(await file.arrayBuffer());
          const timestamp = Date.now();
          const sanitizedFileName = file.name.replace(/[^a-zA-Z0-9.-]/g, '_');
          const s3Key = `uploads/leads/${timestamp}-${sanitizedFileName}`;
          const cloudStoragePath = await uploadFile(buffer, s3Key);
          uploadedFilePaths.push(cloudStoragePath);
        }
      }
    } else {
      // Handle JSON data (for backwards compatibility with CRM)
      data = await request.json();
    }

    // Get session or find admin user for public leads
    const session = await getServerSession(authOptions);

    // For authenticated users (CRM), require proper permissions
    if (session && session.user.role === 'CUSTOMER') {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    // Find admin user to assign as creator for public leads
    let createdById = session?.user?.id;
    if (!createdById) {
      const adminUser = await prisma.user.findFirst({
        where: { role: 'ADMIN' },
        select: { id: true },
      });
      
      if (!adminUser) {
        return NextResponse.json(
          { error: 'System configuration error: No admin user found' },
          { status: 500 }
        );
      }
      
      createdById = adminUser.id;
    }

    // Create the lead
    const lead = await prisma.lead.create({
      data: {
        firstName: data.firstName,
        lastName: data.lastName,
        email: data.email,
        phone: data.phone,
        address: data.address,
        city: data.city,
        state: data.state,
        zipCode: data.zipCode,
        latitude: data.latitude || null,
        longitude: data.longitude || null,
        source: data.source,
        services: data.services || [],
        description: data.description || null,
        budget: data.budget || null,
        timeline: data.timeline || null,
        attachments: uploadedFilePaths,
        status: 'NEW',
        score: 0.0,
        priority: data.priority || 'HIGH',
        assignedToId: data.assignedToId || null,
        createdById: createdById,
        partnerId: data.partnerId || null,
      },
      include: {
        assignedTo: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        createdBy: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
      },
    });

    // Create audit log
    await prisma.auditLog.create({
      data: {
        userId: createdById,
        entityType: 'lead',
        entityId: lead.id,
        action: 'create',
        newData: lead,
        metadata: {
          userRole: session?.user?.role || 'PUBLIC',
          source: data.source,
          isPublicSubmission: !session,
          timestamp: new Date().toISOString(),
        },
      },
    });

    // Send email notifications for public submissions
    if (!session) {
      const serviceType = data.services?.[0] || 'General Service';
      const customerName = `${data.firstName} ${data.lastName}`.trim();
      
      // Send confirmation email to customer
      try {
        await sendEmail({
          to: data.email,
          subject: '✓ Quote Request Received - Quote2Contract',
          html: getCustomerConfirmationEmail(customerName, serviceType),
        });
      } catch (error) {
        console.error('Error sending customer confirmation email:', error);
      }

      // Send notification email to CRM team
      const crmEmail = process.env.CRM_NOTIFICATION_EMAIL || 'quote2contract@gmail.com';
      try {
        await sendEmail({
          to: crmEmail,
          subject: '🚨 New Quote Request - Action Required',
          html: getCrmNotificationEmail({
            name: customerName,
            email: data.email,
            phone: data.phone,
            serviceType,
            address: data.address,
            leadId: lead.id,
          }),
        });
      } catch (error) {
        console.error('Error sending CRM notification email:', error);
      }
    }

    return NextResponse.json(lead, { status: 201 });
  } catch (error) {
    console.error('Error creating lead:', error);
    return NextResponse.json(
      { error: 'Failed to create lead', details: error instanceof Error ? error.message : 'Unknown error' },
      { status: 500 }
    );
  }
}

export async function GET(request: Request) {
  try {
    const session = await getServerSession(authOptions);

    if (!session || session.user.role === 'CUSTOMER') {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const { searchParams } = new URL(request.url);
    const status = searchParams.get('status');
    const priority = searchParams.get('priority');

    const where: any = {};

    if (status) {
      where.status = status;
    }

    if (priority) {
      where.priority = priority;
    }

    const leads = await prisma.lead.findMany({
      where,
      include: {
        assignedTo: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        createdBy: {
          select: {
            id: true,
            name: true,
            email: true,
          },
        },
        quotes: {
          select: {
            id: true,
            quoteNumber: true,
            status: true,
            total: true,
          },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
    });

    return NextResponse.json(leads);
  } catch (error) {
    console.error('Error fetching leads:', error);
    return NextResponse.json(
      { error: 'Failed to fetch leads' },
      { status: 500 }
    );
  }
}
