// app/api/appapis/consultant_student_upload/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';

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

function generateS3Key(consultantId: 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 `consultants/students/${consultantId}/${timestamp}_${uniqueId}_${sanitizedFileName}`;
}

async function uploadToS3(file: any, consultantId: number): Promise<{ s3Key: string; url: string }> {
  try {
    let fileName = file.name || 'document.jpg';
    
    if (fileName.includes('blob:') || fileName.includes('localhost')) {
      const timestamp = Date.now();
      const fileExtension = file.type?.split('/')[1] || 'jpg';
      fileName = `document_${timestamp}.${fileExtension}`;
    }
    
    const fileType = file.type || 'image/jpeg';

    let fileBuffer: Buffer;
    
    if (file.arrayBuffer && typeof file.arrayBuffer === 'function') {
      const arrayBuffer = await file.arrayBuffer();
      fileBuffer = Buffer.from(arrayBuffer);
    } else if (file.uri) {
      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');
    }

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

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

    await s3.send(
      new PutObjectCommand({
        Bucket: bucket,
        Key: s3Key,
        Body: fileBuffer,
        ContentType: fileType,
      })
    );

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

export async function OPTIONS() {
  return NextResponse.json({}, { status: 200 });
}

export async function POST(request: NextRequest) {
  const connection = await pool.getConnection();
  
  try {
    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);
    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 });
    }

    // FIXED: removed generic type parameter
    const [checkConsultant] = await connection.query(
      "SELECT id FROM consultants WHERE user_id = ?",
      [decoded.id]
    ) as RowDataPacket[];

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

    const consultantId = checkConsultant[0].id;

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

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

    let fileToUpload;
    let fileName = 'document.jpg';
    let fileSize = 0;

    if (file && typeof file === 'object' && 'uri' in file) {
      fileToUpload = file;
      fileName = (file as any).name || `document_${Date.now()}.jpg`;
      fileSize = (file as any).size || 0;
    } else if (file instanceof File) {
      fileToUpload = file;
      fileName = file.name;
      fileSize = file.size;
    } else {
      return NextResponse.json({
        success: false,
        message: "Invalid file format"
      }, { status: 400 });
    }

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

    let uploadResult;
    try {
      uploadResult = await uploadToS3(fileToUpload, consultantId);
    } catch (uploadError) {
      console.error('S3 upload failed:', uploadError);
      return NextResponse.json({
        success: false,
        message: "Failed to upload file to storage: " + (uploadError as Error).message
      }, { status: 500 });
    }

    return NextResponse.json({
      success: true,
      message: "File uploaded successfully",
      data: {
        s3Key: uploadResult.s3Key,
        url: uploadResult.url,
        fileName: fileName,
        fileSize: fileSize
      }
    }, { status: 200 });

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