// app/api/appapis/consultant-profile-picture/route.ts
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 consultant 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 `consultant-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,
      })
    );
    console.log('Deleted old S3 file:', key);
    return true;
  } catch (error) {
    console.error('Error deleting from S3:', error);
    return false;
  }
}

export async function POST(request: NextRequest) {
  const connection = await pool.getConnection();
  
  try {
    console.log('\n📸 ===== CONSULTANT 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 !== "consultant") {
      return NextResponse.json({
        success: false,
        message: "You are not authorized to perform this action"
      }, { status: 401 });
    }

    // Verify user exists
    const [checkUser] = await connection.query(
      "SELECT * FROM users WHERE id = ? AND user_type = 'consultant'",
      [decoded.id]
    ) as RowDataPacket[];

    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 });
    }

    // Validate file size (max 5MB)
    const maxSize = 5 * 1024 * 1024;
    if (fileSize > maxSize) {
      return NextResponse.json({
        success: false,
        message: "File too large. Maximum size is 5MB"
      }, { status: 400 });
    }

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

    // Upload new picture to S3
    let profilePictureUrl;
    try {
      // Get file buffer
      let fileBuffer: Buffer;
      
      if (fileToUpload.uri) {
        // React Native format - fetch the file from URI
        const response = await fetch(fileToUpload.uri);
        const arrayBuffer = await response.arrayBuffer();
        fileBuffer = Buffer.from(arrayBuffer);
      } else if (fileToUpload.arrayBuffer) {
        // Native File object
        const arrayBuffer = await fileToUpload.arrayBuffer();
        fileBuffer = Buffer.from(arrayBuffer);
      } else {
        throw new Error('Unable to process file format');
      }

      const s3Key = generateS3Key(decoded.id, 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}`);
      console.log(`   - Buffer size: ${fileBuffer.length} bytes`);

      await s3.send(
        new PutObjectCommand({
          Bucket: bucket,
          Key: s3Key,
          Body: fileBuffer,
          ContentType: file.type || 'image/jpeg',
        })
      );

      const region = process.env.AWS_DEFAULT_REGION || 'eu-north-1';
      profilePictureUrl = `https://${bucket}.s3.${region}.amazonaws.com/${s3Key}`;
      
      console.log('✅ Upload successful, URL:', profilePictureUrl);
    } 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 consultant record
    let updateResult;
    
    if (oldData.length > 0) {
      // Update existing record
      [updateResult] = await connection.query(
        "UPDATE consultants SET profile_picture = ?, updated_at = NOW() WHERE user_id = ?",
        [profilePictureUrl, decoded.id]
      ) as ResultSetHeader[];
      console.log('Updated existing consultant record');
    } else {
      // Create new consultant record
      const [userData] = await connection.query(
        "SELECT first_name, last_name FROM users WHERE id = ?",
        [decoded.id]
      ) as RowDataPacket[];
      
      const fullName = userData.length > 0 
        ? `${userData[0].first_name} ${userData[0].last_name}`
        : 'Consultant';
      
      [updateResult] = await connection.query(
        `INSERT INTO consultants (user_id, name, profile_picture, created_at, updated_at) 
         VALUES (?, ?, ?, NOW(), NOW())`,
        [decoded.id, fullName, profilePictureUrl]
      ) as ResultSetHeader[];
      console.log('Created new consultant record');
    }

    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) {
      console.log('Deleting old picture:', oldPictureUrl);
      await deleteFromS3(oldPictureUrl);
    }

    console.log('✅ Profile picture updated successfully');
    console.log('New picture URL:', profilePictureUrl);

    return NextResponse.json({
      success: true,
      message: "Profile picture updated successfully",
      data: {
        profile_picture: profilePictureUrl,
        s3Key: profilePictureUrl.split('.com/')[1]
      }
    }, { 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();
  }
}