// app/api/frontend/consultant/consultantdashboard/student/add/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import pool from '../../../../lib/db/db';
import { verifyAuthentication } from '../../../utils/verifyAuthentication';
import { ResultSetHeader, RowDataPacket } from 'mysql2';

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

interface FileUploadState {
  passport: string | null;
  photo: string | null;
  educationalDegree: string | null;
  educationalCertificate: string | null;
  recommendationLetter: string | null;
  studyPlan: string | null;
  ieltsOrEnglishProficiency: string | null;
}

interface StudentFormData {
  name: string;
  email: string;
  phone: string;
  passportNumber: string;
  dateOfBirth: string;
  course: string;
  country: string;
  nationality: string;
  university: string;
  files: FileUploadState;
}

// Validation function
function validateStudentData(data: any): { isValid: boolean; errors: string[] } {
  const errors: string[] = [];

  // Required fields validation
  if (!data.name || typeof data.name !== 'string' || data.name.trim().length < 2) {
    errors.push('Full name is required and must be at least 2 characters');
  }

  if (!data.email || typeof data.email !== 'string') {
    errors.push('Email address is required');
  } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
    errors.push('Please enter a valid email address');
  }

  if (!data.phone || typeof data.phone !== 'string') {
    errors.push('Phone number is required');
  }

  if (!data.passportNumber || typeof data.passportNumber !== 'string') {
    errors.push('Passport number is required');
  }

  if (!data.dateOfBirth || typeof data.dateOfBirth !== 'string') {
    errors.push('Date of birth is required');
  }

  if (!data.course || typeof data.course !== 'string') {
    errors.push('Desired course is required');
  }

  if (!data.country || typeof data.country !== 'string') {
    errors.push('Target country is required');
  }

  if (!data.nationality || typeof data.nationality !== 'string') {
    errors.push('Nationality is required');
  }

  // File validation
  if (!data.files || typeof data.files !== 'object') {
    errors.push('Files data is required');
  } else {
    if (!data.files.passport) {
      errors.push('Passport copy is required');
    }
    if (!data.files.photo) {
      errors.push('Passport photo is required');
    }
    if (!data.files.educationalDegree) {
      errors.push('Educational degree is required');
    }
    if (!data.files.educationalCertificate) {
      errors.push('Educational certificate is required');
    }
  }

  return { isValid: errors.length === 0, errors };
}

// Generate S3 key for student files
function generateStudentFileKey(consultantId: number, studentName: string, fileType: string, originalName: string): string {
  const timestamp = Date.now();
  const sanitizedName = studentName.toLowerCase().replace(/\s+/g, '_').replace(/[^a-z0-9_]/g, '');
  const sanitizedFile = originalName.replace(/\s+/g, '_').replace(/[^a-zA-Z0-9._-]/g, '');
  const uniqueId = Math.random().toString(36).substring(2, 9);
  return `consultants/${consultantId}/students/${sanitizedName}/${timestamp}_${uniqueId}_${fileType}_${sanitizedFile}`;
}

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

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

    // Check if user is a consultant
    if (decoded.role !== 'consultant') {
      return NextResponse.json({
        success: false,
        message: 'You are not authorized to perform this action. Consultant access required.'
      }, { status: 403 });
    }

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

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

    const consultantId = decoded.id;

    // Parse request body
    let body: StudentFormData;
    try {
      body = await request.json();
    } catch (error) {
      return NextResponse.json({
        success: false,
        message: 'Invalid JSON in request body'
      }, { status: 400 });
    }

    // Validate form data
    const validation = validateStudentData(body);
    if (!validation.isValid) {
      return NextResponse.json({
        success: false,
        message: 'Validation failed',
        errors: validation.errors
      }, { status: 400 });
    }

    // Start transaction
    await connection.beginTransaction();

    // FIXED: removed generic type parameter
    const [existingStudent] = await connection.query(
      `SELECT id FROM cstudents 
       WHERE email = ? OR passport_number = ?`,
      [body.email, body.passportNumber]
    ) as RowDataPacket[];

    if (existingStudent.length > 0) {
      await connection.rollback();
      return NextResponse.json({
        success: false,
        message: 'A student with this email or passport number already exists'
      }, { status: 409 });
    }

    // Insert student record
    const query = `
      INSERT INTO cstudents (
        name,
        email,
        phone,
        passport_number,
        date_of_birth,
        course_doc,
        intrested_country_doc,
        nationality,
        university,
        passport_doc,
        photo_doc,
        educational_degree_doc,
        educational_certificate_doc,
        recomendation_letter_doc,
        study_plan,
        ielts_english_proficiency_letter,
        consultant_id,
        status,
        created_at,
        updated_at
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', NOW(), NOW())
    `;

    const values = [
      body.name.trim(),
      body.email.toLowerCase().trim(),
      body.phone.trim(),
      body.passportNumber.trim(),
      body.dateOfBirth,
      body.course.trim(),
      body.country.trim(),
      body.nationality.trim(),
      body.university?.trim() || null,
      body.files.passport,
      body.files.photo,
      body.files.educationalDegree,
      body.files.educationalCertificate,
      body.files.recommendationLetter || null,
      body.files.studyPlan || null,
      body.files.ieltsOrEnglishProficiency || null,
      consultantId
    ];

    // FIXED: removed generic type parameter
    const [result] = await connection.query(query, values) as ResultSetHeader[];

    if (result.affectedRows === 0) {
      await connection.rollback();
      return NextResponse.json({
        success: false,
        message: 'Failed to add student'
      }, { status: 500 });
    }

    const studentId = result.insertId;

    // Prepare data for CRM API
    const crmStudentData = {
      name: body.name,
      email: body.email,
      phone: body.phone,
      passport_number: body.passportNumber,
      date_of_birth: body.dateOfBirth,
      course: body.course,
      country: body.country,
      nationality: body.nationality,
      university: body.university,
      passport_doc: body.files.passport,
      photo_doc: body.files.photo,
      educational_degree_doc: body.files.educationalDegree,
      educational_certificate_doc: body.files.educationalCertificate,
      recomendation_letter_doc: body.files.recommendationLetter,
      study_plan: body.files.studyPlan,
      ielts_english_proficiency_letter: body.files.ieltsOrEnglishProficiency,
      consultant_id: consultantId,
      student_id: studentId
    };

    // Send to CRM API (non-blocking - don't fail if CRM fails)
    try {
      const crmResponse = await fetch('https://crm-universitiespage.com/reactapis/api/website_consultants_Students/store', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `${process.env.CRM_API_KEY}`,
        },
        body: JSON.stringify(crmStudentData),
      });

      const crmData = await crmResponse.json();

      if (crmData?.status_code !== 200) {
        console.error('CRM API returned error:', crmData);
        // Don't rollback - just log the error
      }
    } catch (crmError) {
      console.error('Error sending to CRM API:', crmError);
      // Don't rollback - student is already saved locally
    }

    // Commit transaction
    await connection.commit();

    // Return success response
    return NextResponse.json({
      success: true,
      message: 'Student added successfully',
      data: {
        id: studentId,
        name: body.name,
        email: body.email,
        status: 'pending'
      }
    }, { status: 200 });

  } catch (error) {
    await connection.rollback();
    console.error('Error adding student:', error);
    
    return NextResponse.json({
      success: false,
      message: 'Internal server error',
      error: process.env.NODE_ENV === 'development' ? (error as Error).message : undefined
    }, { status: 500 });
  } finally {
    connection.release();
  }
}