// app/api/frontend/register-foreign-student/route.js
import { NextResponse } from 'next/server';
import { z } from 'zod';
import bcrypt from 'bcryptjs';
import pool from '../../../../lib/db/db';

// Enhanced password validation helper
const passwordSchema = z.string()
  .min(8, 'Password must be at least 8 characters')
  .regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
  .regex(/[a-z]/, 'Password must contain at least one lowercase letter')
  .regex(/[0-9]/, 'Password must contain at least one number')
  .regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character')
  .max(100, 'Password cannot exceed 100 characters');

// Enhanced validation schema with all fields required
const registerSchema = z.object({
  name: z.string()
    .min(2, 'Name must be at least 2 characters')
    .max(255, 'Name cannot exceed 255 characters')
    .refine(value => value.trim().length > 0, {
      message: 'Name is required'
    }),
  
  email: z.string()
    .email('Invalid email address')
    .max(255, 'Email cannot exceed 255 characters')
    .refine(value => value.trim().length > 0, {
      message: 'Email is required'
    }),
  
  password: passwordSchema
    .refine(value => value.trim().length > 0, {
      message: 'Password is required'
    }),
  
  confirm_password: z.string()
    .refine(value => value.trim().length > 0, {
      message: 'Please confirm your password'
    }),
  
  phone: z.string()
    .min(5, 'Phone number must be at least 5 characters')
    .max(20, 'Phone number cannot exceed 20 characters')
    .regex(/^[\+]?[1-9][\d\s\-\(\)\.]{5,}$/, 'Invalid phone number format')
    .refine(value => value.trim().length > 0, {
      message: 'Phone number is required'
    }),
  
  country_id: z.coerce.number()
    .int('Country must be a valid ID')
    .positive('Country is required')
    .refine(value => value > 0, {
      message: 'Country is required'
    }),
  
  about_me: z.string()
    .min(10, 'About me must be at least 10 characters')
    .max(2000, 'About me cannot exceed 2000 characters')
    .refine(value => value.trim().length > 0, {
      message: 'About yourself is required'
    }),
  
  profile_picture: z.string()
    .min(1, 'Profile picture is required')
    .refine(value => value.trim().length > 0, {
      message: 'Profile picture is required'
    }),
  
  hour_rate: z.coerce.number()
    .min(0.01, 'Hourly rate must be greater than 0')
    .max(1000, 'Hourly rate cannot exceed $1000')
    .refine(value => value > 0, {
      message: 'Hourly rate is required and must be greater than 0'
    }),
  
  gender: z.enum(['male', 'female', 'other'], {
    errorMap: () => ({ message: 'Gender is required. Must be male, female, or other' })
  })
  .refine(value => !!value, {
    message: 'Gender is required'
  }),
  
  experience: z.string()
    .min(10, 'Experience must be at least 10 characters')
    .max(5000, 'Experience cannot exceed 5000 characters')
    .refine(value => value.trim().length > 0, {
      message: 'Experience is required'
    }),
  
  last_education: z.enum([
    'high_school',
    'bachelors', 
    'masters',
    'phd',
    'diploma',
    'certificate'
  ], {
    errorMap: () => ({ message: 'Education level is required. Select from the available options' })
  })
  .refine(value => !!value, {
    message: 'Education level is required'
  }),
  
  terms_accepted: z.boolean()
    .refine(val => val === true, {
      message: 'You must accept the terms and conditions'
    })
}).refine((data) => data.password === data.confirm_password, {
  message: "Passwords don't match",
  path: ["confirm_password"],
});

// Function to generate slug from name
function generateSlug(name) {
  if (!name) return '';
  
  // Convert to lowercase
  let slug = name.toLowerCase();
  
  // Remove special characters except hyphens
  slug = slug.replace(/[^a-z0-9\s-]/g, '');
  
  // Replace spaces with hyphens
  slug = slug.replace(/\s+/g, '-');
  
  // Remove multiple consecutive hyphens
  slug = slug.replace(/-+/g, '-');
  
  // Trim hyphens from start and end
  slug = slug.replace(/^-+|-+$/g, '');
  
  return slug;
}

// Function to generate unique slug
async function generateUniqueSlug(connection, name, maxAttempts = 5) {
  if (!name) throw new Error('Name is required to generate slug');
  
  let baseSlug = generateSlug(name);
  if (!baseSlug) throw new Error('Could not generate slug from name');
  
  let slug = baseSlug;
  let attempts = 0;
  
  while (attempts < maxAttempts) {
    // Check if slug exists in database
    const [existingSlugs] = await connection.query(
      'SELECT id FROM foreign_students WHERE user_slug = ?',
      [slug]
    );
    
    // If slug doesn't exist, return it
    if (existingSlugs.length === 0) {
      return slug;
    }
    
    // If slug exists, add random numbers and try again
    attempts++;
    if (attempts === 1) {
      // First retry: Add random 4-digit number
      const randomSuffix = Math.floor(1000 + Math.random() * 9000);
      slug = `${baseSlug}-${randomSuffix}`;
    } else {
      // Subsequent retries: Add incrementing number
      slug = `${baseSlug}-${1000 + attempts}`;
    }
  }
  
  // If all attempts fail, generate completely random slug
  const timestamp = Date.now().toString().slice(-6);
  const randomNum = Math.floor(1000 + Math.random() * 9000);
  return `${baseSlug}-${timestamp}-${randomNum}`;
}

export async function POST(request) {
  let connection;
  try {
    const body = await request.json();
    connection = await pool.getConnection();
    
    await connection.beginTransaction();
    
    // Validate input
    const validatedData = registerSchema.parse(body);
    
    // Additional validations
    
    // Check if email already exists
    const [existingUsers] = await connection.query(
      'SELECT id FROM foreign_students WHERE email = ?',
      [validatedData.email]
    );
    
    if (existingUsers.length > 0) {
      return NextResponse.json(
        { 
          success: false,
          message: 'Registration failed',
          errors: { email: 'Email already registered. Please use a different email or login.' }
        },
        { status: 400 }
      );
    }
    
    // Check if country exists
    const [countryExists] = await connection.query(
      'SELECT id FROM countries_db WHERE id = ?',
      [validatedData.country_id]
    );
    
    if (countryExists.length === 0) {
      return NextResponse.json(
        { 
          success: false,
          message: 'Registration failed',
          errors: { country_id: 'Selected country does not exist' }
        },
        { status: 400 }
      );
    }
    
    // Generate unique slug
    const userSlug = await generateUniqueSlug(connection, validatedData.name);
    
    // Hash the password
    const salt = await bcrypt.genSalt(10);
    const passwordHash = await bcrypt.hash(validatedData.password, salt);
    
    // Insert new foreign student with user_slug
    const [result] = await connection.query(
      `INSERT INTO foreign_students 
       (name, email, password_hash, phone, country_id, about_me, profile_picture, 
        hour_rate, gender, experience, last_education, user_slug, is_active)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      [
        validatedData.name.trim(),
        validatedData.email.trim(),
        passwordHash,
        validatedData.phone.trim(),
        validatedData.country_id,
        validatedData.about_me.trim(),
        validatedData.profile_picture,
        validatedData.hour_rate,
        validatedData.gender,
        validatedData.experience.trim(),
        validatedData.last_education,
        userSlug,
        0 // Set is_active to 0 initially (needs admin approval)
      ]
    );
    
    // Get country name for CRM
    const [getCountry] = await connection.query(
      'SELECT name FROM countries_db WHERE id = ?',
      [validatedData.country_id]
    );

    if (getCountry.length === 0) {
      await connection.rollback();
      return NextResponse.json(
        { 
          success: false,
          message: 'Registration failed',
          errors: { country_id: 'Country not found' }
        },
        { status: 400 }
      );
    }

    // Prepare CRM payload
    const crmPayload = {
      user_id: result.insertId,
      name: validatedData.name,
      email: validatedData.email,
      phone: validatedData.phone,
      country: getCountry[0].name,
      about_me: validatedData.about_me,
      profile_picture: validatedData.profile_picture,
      hour_rate: validatedData.hour_rate,
      gender: validatedData.gender,
      experience: validatedData.experience,
      last_education: validatedData.last_education,
      registration_date: new Date().toISOString()
    };

    // Send to CRM API
    let crmResponse;
    try {
      crmResponse = await fetch(
        "https://crm-universitiespage.com/reactapis/api/website_foreign_student/store",
        {
          method: "POST",
          body: JSON.stringify(crmPayload),
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `${process.env.CRM_API_KEY}`,
          },
        }
      );

      if (!crmResponse.ok) {
        throw new Error(`CRM API responded with status: ${crmResponse.status}`);
      }

      const crmData = await crmResponse.json();

      if (!crmData || crmData?.status_code !== 200) {
        throw new Error('CRM API returned non-success status');
      }

      // Commit transaction if CRM call succeeds
      await connection.commit();

      // Return success response
      return NextResponse.json({
        success: true,
        message: 'Registration successful! Your account is pending approval. You will be notified via email once activated.',
        studentId: result.insertId,
        userSlug: userSlug,
        data: {
          name: validatedData.name,
          email: validatedData.email,
          status: 'pending_approval'
        }
      }, { status: 201 });
      
    } catch (crmError) {
      await connection.rollback();
      console.error('CRM API Error:', crmError);
      
      return NextResponse.json(
        {
          success: false,
          message: "Failed to complete registration. Please try again later.",
          errors: { system: 'Unable to process registration at this time' }
        },
        { status: 502 }
      );
    }
    
  } catch (error) {
    // Rollback transaction if it exists
    if (connection) {
      await connection.rollback();
    }
    
    console.error('Registration error:', error);
    
    // Zod validation errors
    if (error instanceof z.ZodError) {
      const errors = {};
      error.errors.forEach(err => {
        const path = err.path.join('.');
        errors[path] = err.message;
      });
      
      return NextResponse.json(
        { 
          success: false,
          message: 'Validation failed. Please check all required fields.',
          errors 
        },
        { status: 400 }
      );
    }
    
    // Database or other errors
    return NextResponse.json(
      { 
        success: false,
        message: 'Registration failed due to server error',
        errors: { system: error.message || 'Internal server error' }
      },
      { status: 500 }
    );
  } finally {
    // Release connection if it exists
    if (connection) {
      connection.release();
    }
  }
}