import { NextRequest, NextResponse } from 'next/server';
import pool from '../../../../lib/db/db';
import { verifyAuthentication } from '../../../utils/verifyAuthentication';
import { ResultSetHeader, RowDataPacket } from 'mysql2';
import { S3Client, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';

// S3 Client configuration
const s3 = new S3Client({
  region: process.env.AWS_DEFAULT_REGION || 'eu-north-1',
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || '',
  },
});

interface TokenInterface {
  id: number;
  userId?: number;
  email?: string;
  role?: string;
}

// Helper function to generate S3 key for profile pictures
function generateS3Key(userId: number, fileName: string): string {
  const timestamp = Date.now();
  const sanitizedFileName = fileName.replace(/\s+/g, '_').replace(/[^a-zA-Z0-9._-]/g, '');
  const uniqueId = Math.random().toString(36).substring(2, 9);
  return `student-profiles/${userId}/${timestamp}_${uniqueId}_${sanitizedFileName}`;
}

// Helper function to delete file from S3
async function deleteFromS3(url: string): Promise<boolean> {
  try {
    const bucket = process.env.AWS_BUCKET;
    if (!bucket || !url.includes(bucket)) return false;
    
    const key = url.split(`${bucket}/`)[1];
    if (!key) return false;
    
    await s3.send(
      new DeleteObjectCommand({
        Bucket: bucket,
        Key: key,
      })
    );
    return true;
  } catch (error) {
    console.error('Error deleting from S3:', error);
    return false;
  }
}

// Helper function to upload file to S3
async function uploadToS3(file: any, userId: number): Promise<string> {
  try {
    // console.log('📤 Starting S3 upload...');
    
    // Get file details
    const fileName = file.name || 'profile.jpg';
    const fileType = file.type || 'image/jpeg';
    
    // console.log(`   - File name: ${fileName}`);
    // console.log(`   - File type: ${fileType}`);

    // Get file buffer based on format
    let fileBuffer: Buffer;
    
    if (file.arrayBuffer && typeof file.arrayBuffer === 'function') {
      // Native File object
      const arrayBuffer = await file.arrayBuffer();
      fileBuffer = Buffer.from(arrayBuffer);
    } else if (file.uri) {
      // React Native format - need to fetch
      const response = await fetch(file.uri);
      const arrayBuffer = await response.arrayBuffer();
      fileBuffer = Buffer.from(arrayBuffer);
    } else if (Buffer.isBuffer(file)) {
      fileBuffer = file;
    } else {
      throw new Error('Unable to process file format');
    }

    // console.log(`   - Buffer size: ${fileBuffer.length} bytes`);

    const s3Key = generateS3Key(userId, fileName);
    const bucket = process.env.AWS_BUCKET;

    if (!bucket) {
      throw new Error('AWS bucket not configured');
    }

    // console.log(`   - Target bucket: ${bucket}`);
    // console.log(`   - Target key: ${s3Key}`);

    // Upload to S3 WITHOUT ACL
    await s3.send(
      new PutObjectCommand({
        Bucket: bucket,
        Key: s3Key,
        Body: fileBuffer,
        ContentType: fileType,
        // Remove ACL line - bucket doesn't allow it
      })
    );

    const region = process.env.AWS_DEFAULT_REGION || 'eu-north-1';
    const fileUrl = `https://${bucket}.s3.${region}.amazonaws.com/${s3Key}`;
    
    // console.log('✅ Upload successful, URL:', fileUrl);
    
    return fileUrl;
  } catch (uploadError) {
    console.error('❌ S3 upload error:', uploadError);
    throw uploadError;
  }
}

// Handle OPTIONS for CORS preflight
export async function OPTIONS() {
  return NextResponse.json({}, { status: 200 });
}

export async function PUT(request: NextRequest) {
  const connection = await pool.getConnection();
  
  try {
    // console.log('\n📸 ===== PROFILE PICTURE UPLOAD STARTED =====');
    
    // Get token from Authorization header
    const authHeader = request.headers.get('authorization');
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return NextResponse.json({
        success: false,
        message: "No valid authorization header found"
      }, { status: 401 });
    }

    const token = authHeader.substring(7);
    
    // Verify token
    const authResult = await verifyAuthentication(token);
    
    if (authResult instanceof NextResponse) {
      return authResult;
    }
    
    const decoded = authResult as TokenInterface;
    
    if (!decoded || !decoded.id) {
      return NextResponse.json({
        success: false,
        message: "Invalid token - no user ID found"
      }, { status: 401 });
    }

    if (decoded.role !== "foreign-student") {
      return NextResponse.json({
        success: false,
        message: "You are not authorized to perform this action"
      }, { status: 401 });
    }

    // Verify user exists
    const [checkUser] = await connection.query<RowDataPacket[]>(
      "SELECT * FROM foreign_students WHERE id = ?",
      [decoded.id]
    );

    if (checkUser.length === 0) {
      return NextResponse.json({
        success: false,
        message: "User not found"
      }, { status: 404 });
    }

    // Get the file from FormData
    const contentType = request.headers.get('content-type') || '';
    if (!contentType.includes('multipart/form-data')) {
      return NextResponse.json({
        success: false,
        message: "Request must be multipart/form-data"
      }, { status: 400 });
    }

    const formData = await request.formData();
    const file = formData.get('profile_picture');

    if (!file) {
      return NextResponse.json({
        success: false,
        message: "No file uploaded"
      }, { status: 400 });
    }

    // console.log('📄 Received file type:', typeof file);
    
    // Handle React Native's special format
    let fileToUpload;
    let fileName = 'profile.jpg';
    let fileSize = 0;

    // Check if it's the React Native format (has uri property)
    if (file && typeof file === 'object' && 'uri' in file) {
      // console.log('📱 Detected React Native file format');
      fileToUpload = file;
      fileName = (file as any).name || `profile_${Date.now()}.jpg`;
      fileSize = (file as any).size || 0;
      // console.log(`   - URI: ${(file as any).uri}`);
      // console.log(`   - Name: ${fileName}`);
      // console.log(`   - Size: ${fileSize} bytes`);
    } else if (file instanceof File) {
      // console.log('💻 Detected native File object');
      fileToUpload = file;
      fileName = file.name;
      fileSize = file.size;
      // console.log(`   - Name: ${fileName}`);
      // console.log(`   - Size: ${fileSize} bytes`);
      // console.log(`   - Type: ${file.type}`);
    } else {
      // console.log('❌ Unknown file format:', file);
      return NextResponse.json({
        success: false,
        message: "Invalid file format"
      }, { status: 400 });
    }

    // Get old profile picture URL before uploading new one
    const [oldData] = await connection.query<RowDataPacket[]>(
      "SELECT profile_picture FROM foreign_students WHERE id = ?",
      [decoded.id]
    );
    const oldPictureUrl = oldData.length > 0 ? oldData[0].profile_picture : null;

    // Upload new picture to S3
    let profilePictureUrl;
    try {
      profilePictureUrl = await uploadToS3(fileToUpload, decoded.id);
    } catch (uploadError) {
      console.error('S3 upload failed:', uploadError);
      return NextResponse.json({
        success: false,
        message: "Failed to upload image to storage: " + (uploadError as Error).message
      }, { status: 500 });
    }

    // Update user record with new picture URL
    const [updateResult] = await connection.query<ResultSetHeader>(
      "UPDATE foreign_students SET profile_picture = ?, updated_at = NOW() WHERE id = ?",
      [profilePictureUrl, decoded.id]
    );

    if (updateResult.affectedRows === 0) {
      // If update failed, try to delete the uploaded file
      await deleteFromS3(profilePictureUrl);
      return NextResponse.json({
        success: false,
        message: "Failed to update profile picture in database"
      }, { status: 500 });
    }


    

    // Delete old picture from S3 if it exists and is different
    if (oldPictureUrl && oldPictureUrl !== profilePictureUrl) {
      await deleteFromS3(oldPictureUrl);
    }

    return NextResponse.json({
      success: true,
      message: "Profile picture updated successfully",
      data: {
        profile_picture: profilePictureUrl
      }
    }, { status: 200 });

  } catch (error) {
    console.error('Profile picture upload error:', error);
    return NextResponse.json({
      success: false,
      message: "Internal server error: " + (error as Error).message
    }, { status: 500 });
  } finally {
    connection.release();
  }
}