// app/api/appapis/foreign-student-profile/route.js
import pool from '../../../../lib/db/db';
import { NextRequest, NextResponse } from 'next/server';
import { RowDataPacket } from 'mysql2';
import { verifyAuthentication } from '../../../utils/verifyAuthentication';
import { z } from 'zod';

type UpdatedFields = {
  name?: string;
  phone?: string | null;
  country_id?: number | null;
  about_me?: string | null;
  profile_picture?: string | null;
  hour_rate?: number;
  gender?: string | null;
  experience?: string | null;
  last_education?: string | null;
};

const profileSchema = z.object({
  name: z.string()
    .min(2, 'Name must be at least 2 characters')
    .max(255, 'Name cannot exceed 255 characters')
    .optional(),

  phone: z.string()
    .regex(/^[\+]?[1-9][\d]{0,15}$/, 'Invalid phone number')
    .optional()
    .or(z.literal('')),

  country_id: z.coerce.number()
    .int('Country must be a valid ID')
    .positive('Country is required')
    .optional(),

  about_me: z.string()
    .max(2000, 'About me cannot exceed 2000 characters')
    .optional()
    .or(z.literal('')),

  profile_picture: z.string()
    .optional()
    .or(z.literal('')),

  hour_rate: z.coerce.number()
    .min(0, 'Hour rate cannot be negative')
    .max(1000, 'Hour rate cannot exceed $1000')
    .optional()
    .default(0),

  gender: z.enum(['male', 'female', 'other'], {
    errorMap: () => ({ message: 'Gender must be male, female, or other' })
  }).optional(),

  experience: z.string()
    .max(5000, 'Experience cannot exceed 5000 characters')
    .optional()
    .or(z.literal('')),

  last_education: z.enum([
    'high_school',
    'bachelors', 
    'masters',
    'phd',
    'diploma',
    'certificate'
  ], {
    errorMap: () => ({ message: 'Invalid education level' })
  }).optional(),
});

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-api-key',
  'Access-Control-Allow-Credentials': 'true',
};

export async function OPTIONS() {
  return new NextResponse(null, {
    status: 204,
    headers: corsHeaders,
  });
}

export async function GET(request: NextRequest) {
  const connection = await pool.getConnection();
  
  try {
    // Get token from Authorization header
    const authHeader = request.headers.get('authorization');
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'No valid authorization header found' 
        },
        { status: 401, headers: corsHeaders }
      );
    }

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

    // Check if user is a foreign student
    if (decoded.role !== 'foreign-student') {
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Access denied. Foreign student access only.' 
        },
        { status: 403, headers: corsHeaders }
      );
    }

    // Fetch foreign student data
    const [studentData] = await connection.query<RowDataPacket[]>(
      `SELECT 
        fs.id, 
        fs.name, 
        fs.email, 
        fs.phone, 
        fs.country_id, 
        c.name as country_name,
        fs.about_me, 
        fs.profile_picture, 
        fs.hour_rate, 
        fs.gender, 
        fs.experience, 
        fs.last_education,
        fs.is_active, 
        fs.is_verified,
        fs.email_verified,
        fs.created_at, 
        fs.updated_at
      FROM foreign_students fs
      LEFT JOIN countries_db c ON fs.country_id = c.id
      WHERE fs.id = ? AND fs.is_active = 1 
      LIMIT 1`, 
      [decoded.id]
    );

    if (studentData.length === 0) {
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Student not found or account inactive' 
        },
        { status: 404, headers: corsHeaders }
      );
    }

    connection.release();

    return NextResponse.json({
      success: true,
      message: 'Profile fetched successfully',
      data: studentData[0]
    }, { status: 200, headers: corsHeaders });

  } catch (err: any) {
    console.error('Get profile error:', err);
    connection.release();
    return NextResponse.json(
      { 
        success: false, 
        message: 'Internal server error' 
      },
      { status: 500, headers: corsHeaders }
    );
  }
}

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

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

    // Check if user is a foreign student
    if (decoded.role !== 'foreign-student') {
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Access denied. Foreign student access only.' 
        },
        { status: 403, headers: corsHeaders }
      );
    }

    const body = await request.json();
    
    // Validate input
    const validatedData = profileSchema.parse(body);

    // Start transaction
    await connection.beginTransaction();

    // Check if foreign student exists and get current data
    const [existingStudent] = await connection.query<RowDataPacket[]>(
      `SELECT 
        id, name, email, phone, country_id, about_me, profile_picture, 
        hour_rate, gender, experience, last_education
      FROM foreign_students 
      WHERE id = ? AND is_active = 1 
      LIMIT 1`,
      [decoded.id]
    );

    if (existingStudent.length === 0) {
      await connection.rollback();
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Student not found or account inactive' 
        },
        { status: 404, headers: corsHeaders }
      );
    }

    const currentData = existingStudent[0];

    // Build update query dynamically
    const updateFields = [];
    const updateValues = [];

    // Track which fields are being updated
    const updatedFields: Partial<UpdatedFields> = {};

    // Add fields to update
    if (validatedData.name !== undefined && validatedData.name !== currentData.name) {
      updateFields.push('name = ?');
      updateValues.push(validatedData.name);
      updatedFields.name = validatedData.name;
    }

    if (validatedData.phone !== undefined && validatedData.phone !== currentData.phone) {
      updateFields.push('phone = ?');
      updateValues.push(validatedData.phone || null);
      updatedFields.phone = validatedData.phone || null;
    }

    if (validatedData.country_id !== undefined && validatedData.country_id !== currentData.country_id) {
      updateFields.push('country_id = ?');
      updateValues.push(validatedData.country_id || null);
      updatedFields.country_id = validatedData.country_id || null;
    }

    if (validatedData.about_me !== undefined && validatedData.about_me !== currentData.about_me) {
      updateFields.push('about_me = ?');
      updateValues.push(validatedData.about_me || null);
      updatedFields.about_me = validatedData.about_me || null;
    }

    if (validatedData.profile_picture !== undefined && validatedData.profile_picture !== currentData.profile_picture) {
      updateFields.push('profile_picture = ?');
      updateValues.push(validatedData.profile_picture || null);
      updatedFields.profile_picture = validatedData.profile_picture || null;
    }

    if (validatedData.hour_rate !== undefined && validatedData.hour_rate !== currentData.hour_rate) {
      updateFields.push('hour_rate = ?');
      updateValues.push(validatedData.hour_rate);
      updatedFields.hour_rate = validatedData.hour_rate;
    }

    if (validatedData.gender !== undefined && validatedData.gender !== currentData.gender) {
      updateFields.push('gender = ?');
      updateValues.push(validatedData.gender || null);
      updatedFields.gender = validatedData.gender || null;
    }

    if (validatedData.experience !== undefined && validatedData.experience !== currentData.experience) {
      updateFields.push('experience = ?');
      updateValues.push(validatedData.experience || null);
      updatedFields.experience = validatedData.experience || null;
    }

    if (validatedData.last_education !== undefined && validatedData.last_education !== currentData.last_education) {
      updateFields.push('last_education = ?');
      updateValues.push(validatedData.last_education || null);
      updatedFields.last_education = validatedData.last_education || null;
    }

    // Only proceed if there are fields to update
    if (updateFields.length === 0) {
      await connection.rollback();
      connection.release();
      return NextResponse.json({
        success: true,
        message: 'No changes detected',
        data: currentData
      }, { status: 200, headers: corsHeaders });
    }

    // Always update the updated_at timestamp
    updateFields.push('updated_at = NOW()');

    // Add the WHERE condition value
    updateValues.push(decoded.id);

    // Execute update
    const query = `UPDATE foreign_students SET ${updateFields.join(', ')} WHERE id = ?`;
    
    await connection.query(query, updateValues);

    // Fetch updated data
    const [updatedStudent] = await connection.query<RowDataPacket[]>(
      `SELECT 
        fs.*, 
        c.name as country_name
      FROM foreign_students fs
      LEFT JOIN countries_db c ON fs.country_id = c.id
      WHERE fs.id = ? 
      LIMIT 1`, 
      [decoded.id]
    );

    if (updatedStudent.length === 0) {
      await connection.rollback();
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Failed to fetch updated data' 
        },
        { status: 500, headers: corsHeaders }
      );
    }

    const updatedData = updatedStudent[0];

    // Commit transaction
    await connection.commit();

    // Remove sensitive data before sending response
    const { ...userResponse } = updatedData;

    connection.release();
    
    return NextResponse.json({
      success: true,
      message: 'Profile updated successfully',
      data: userResponse
    }, { status: 200, headers: corsHeaders });

  } catch (err: any) {
    // Rollback on any error
    if (connection) {
      await connection.rollback();
    }
    
    console.error('Update profile error:', err);
    
    // Zod validation errors
    if (err instanceof z.ZodError) {
      const errors = {};
      err.errors.forEach(error => {
        const path = error.path.join('.');
        errors[path] = error.message;
      });
      
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Validation failed', 
          errors 
        },
        { status: 400, headers: corsHeaders }
      );
    }
    
    // Database or other errors
    connection.release();
    return NextResponse.json(
      { 
        success: false, 
        message: err.message || 'Failed to update profile' 
      },
      { status: 500, headers: corsHeaders }
    );
  }
}