import { uploadFile, createBucketIfNotExists, getMinioClient } from '~/server/utils/minio';
import { updateInterestEOIDocument } from '~/server/utils/nocodb';
import { requireAuth } from '~/server/utils/auth';
import formidable from 'formidable';
import { promises as fs } from 'fs';
import mime from 'mime-types';

export default defineEventHandler(async (event) => {
  console.log('[EOI Upload] Request received');

  // Check authentication (x-tag header OR Keycloak session)
  await requireAuth(event);

  try {
    // Get interestId from query params
    const query = getQuery(event);
    const interestId = query.interestId as string;
    
    console.log('[EOI Upload] Interest ID:', interestId);
    
    if (!interestId) {
      console.error('[EOI Upload] No interest ID provided');
      throw createError({
        statusCode: 400,
        statusMessage: 'Interest ID is required',
      });
    }

    // Ensure bucket exists
    console.log('[EOI Upload] Ensuring client-portal bucket exists');
    await createBucketIfNotExists('client-portal');
    
    // Parse multipart form data
    const form = formidable({
      maxFileSize: 50 * 1024 * 1024, // 50MB limit
      keepExtensions: true,
    });
    
    console.log('[EOI Upload] Parsing multipart form data');
    const [fields, files] = await form.parse(event.node.req);
    
    // Handle the uploaded file
    const uploadedFile = Array.isArray(files.file) ? files.file[0] : files.file;
    
    if (!uploadedFile) {
      console.error('[EOI Upload] No file uploaded in request');
      throw createError({
        statusCode: 400,
        statusMessage: 'No file uploaded',
      });
    }
    
    console.log('[EOI Upload] File received:', {
      originalFilename: uploadedFile.originalFilename,
      size: uploadedFile.size,
      mimetype: uploadedFile.mimetype
    });
    
    // Read file buffer
    console.log('[EOI Upload] Reading file from disk');
    const fileBuffer = await fs.readFile(uploadedFile.filepath);
    
    // Generate filename with timestamp - ensure it goes to EOIs folder
    const timestamp = Date.now();
    const sanitizedName = uploadedFile.originalFilename?.replace(/[^a-zA-Z0-9.-]/g, '_') || 'eoi-document.pdf';
    const fileName = `EOIs/${interestId}-${timestamp}-${sanitizedName}`;
    
    console.log('[EOI Upload] Generated filename:', fileName);
    
    // Get content type
    const contentType = mime.lookup(uploadedFile.originalFilename || '') || 'application/pdf';
    console.log('[EOI Upload] Content type:', contentType);
    
    // Upload to MinIO client-portal bucket
    console.log('[EOI Upload] Uploading to MinIO client-portal bucket');
    const client = getMinioClient();
    
    try {
      await client.putObject('client-portal', fileName, fileBuffer, fileBuffer.length, {
        'Content-Type': contentType,
      });
      console.log('[EOI Upload] Successfully uploaded to MinIO');
    } catch (minioError: any) {
      console.error('[EOI Upload] MinIO upload failed:', minioError);
      throw new Error(`Failed to upload to MinIO: ${minioError.message}`);
    }
    
    // Clean up temp file
    console.log('[EOI Upload] Cleaning up temp file');
    await fs.unlink(uploadedFile.filepath);
    
    // Get download URL for the uploaded file
    console.log('[EOI Upload] Generating presigned URL');
    const url = await client.presignedGetObject('client-portal', fileName, 24 * 60 * 60); // 24 hour expiry
    
    // Prepare document data for database
    const documentData = {
      title: uploadedFile.originalFilename || 'EOI Document',
      filename: fileName,
      url: url,
      size: uploadedFile.size,
      uploadedAt: new Date().toISOString()
    };
    
    // Update interest with EOI document information
    console.log('[EOI Upload] Updating interest with EOI document info');
    console.log('[EOI Upload] Document data:', JSON.stringify(documentData, null, 2));
    
    try {
      await updateInterestEOIDocument(interestId, documentData);
      console.log('[EOI Upload] Successfully updated EOI document in database');
    } catch (dbError: any) {
      console.error('[EOI Upload] Failed to update database with EOI document:', dbError);
      console.error('[EOI Upload] Database error details:', dbError.data || dbError.message);
      throw new Error(`Failed to update database: ${dbError.message}`);
    }
    
    // Update the status fields for uploaded (signed) EOI
    const updateData: any = {
      'EOI Status': 'Signed',
      'EOI Time Sent': new Date().toISOString(),
      'Sales Process Level': 'Signed LOI and NDA'
    };
    console.log('[EOI Upload] Updating interest status fields for signed EOI');
    console.log('[EOI Upload] Status update data:', JSON.stringify(updateData, null, 2));
    
    try {
      // Update the interest - forward authentication cookies for internal API call
      const cookies = getRequestHeader(event, "cookie");
      const requestHeaders: Record<string, string> = {};
      if (cookies) {
        requestHeaders["cookie"] = cookies;
      }
      
      await $fetch('/api/update-interest', {
        method: 'POST',
        headers: requestHeaders,
        body: {
          id: interestId,
          data: updateData
        }
      });
      console.log('[EOI Upload] Successfully updated interest status');
    } catch (statusError: any) {
      console.error('[EOI Upload] Failed to update interest status:', statusError);
      console.error('[EOI Upload] Status error details:', statusError.data || statusError.message);
      // Don't throw here - the file was uploaded successfully
    }
    
    console.log('[EOI Upload] Upload completed successfully');
    return {
      success: true,
      document: documentData,
      message: 'EOI document uploaded successfully',
    };
  } catch (error: any) {
    console.error('[EOI Upload] Failed to upload EOI document:', error);
    console.error('[EOI Upload] Error stack:', error.stack);
    throw createError({
      statusCode: 500,
      statusMessage: error.message || 'Failed to upload EOI document',
    });
  }
});

async function getCurrentSalesLevel(interestId: string, event: any): Promise<string> {
  try {
    // Forward authentication cookies for internal API call
    const cookies = getRequestHeader(event, "cookie");
    const requestHeaders: Record<string, string> = {};
    if (cookies) {
      requestHeaders["cookie"] = cookies;
    }
    
    const interest = await $fetch(`/api/get-interest-by-id`, {
      headers: requestHeaders,
      params: {
        id: interestId,
      },
    });
    return interest['Sales Process Level'] || '';
  } catch (error) {
    console.error('Failed to get current sales level:', error);
    return '';
  }
}

function shouldUpdateSalesLevel(currentLevel: string): boolean {
  const levelsBeforeLOI = [
    'General Qualified Interest',
    'Specific Qualified Interest'
  ];
  return levelsBeforeLOI.includes(currentLevel);
}
