import { NextRequest, NextResponse } from 'next/server';
import pool from '../../../../lib/db/db';
import { verifyAuthentication } from '../../../utils/verifyAuthentication';
import { ResultSetHeader, RowDataPacket } from 'mysql2';

interface TokenInterface {
  id: number;
  userId?: number;
  email?: string;
  role?: string;
}

// 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 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 !== "student") {
      return NextResponse.json({
        success: false,
        message: "You are not authorized to perform this action"
      }, { status: 401 });
    }

    // Get user profile data from both tables
    const [getUser] = await connection.query<RowDataPacket[]>(
      `SELECT 
          u.id,
          u.first_name,
          u.last_name,
          u.email,
          u.phone,
          u.image as profile_picture,
          s.nationality,
          s.gender,
          s.city,
          s.state,
          s.prefered_program
      FROM users u
      LEFT JOIN students s ON u.id = s.user_id
      WHERE u.id = ? AND u.user_type = 'student'`,
      [decoded.id]
    );

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

    const userData = getUser[0];

    const formattedData = {
      id: userData.id,
      first_name: userData.first_name || '',
      last_name: userData.last_name || '',
      email: userData.email || '',
      phone: userData.phone || '',
      profile_picture: userData.profile_picture || null,
      nationality: userData.nationality?.toString() || '',
      gender: userData.gender || '',
      prefered_program: userData.prefered_program || '',
      city: userData.city?.toString() || '',
      state: userData.state?.toString() || '',
    };

    return NextResponse.json({
      success: true,
      message: "Profile fetched successfully",
      data: formattedData
    }, { status: 200 });

  } catch (err: any) {
    console.error('Profile fetch error:', err);
    return NextResponse.json({
      success: false,
      message: "Internal server error"
    }, { status: 500 });
  } finally {
    connection.release();
  }
}

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 ')) {
      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 !== "student") {
      return NextResponse.json({
        success: false,
        message: "You are not authorized to perform this action"
      }, { status: 401 });
    }

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

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

    // Only accept JSON requests for profile data
    const contentType = request.headers.get('content-type') || '';
    if (!contentType.includes('application/json')) {
      return NextResponse.json({
        success: false,
        message: "Content-Type must be application/json"
      }, { status: 400 });
    }

    const body = await request.json();
    const {
      first_name,
      last_name,
      phone,
      nationality,
      state,
      city,
      program_type,
      gender,
    } = body;

    // Start transaction
    await connection.beginTransaction();

    // Update users table
    const userUpdateQuery = `
      UPDATE users 
      SET 
        first_name = COALESCE(?, first_name),
        last_name = COALESCE(?, last_name),
        phone = COALESCE(?, phone),
        updated_at = NOW()
      WHERE id = ? AND user_type = 'student'
    `;
    
    const [userResult] = await connection.query<ResultSetHeader>(
      userUpdateQuery,
      [first_name || null, last_name || null, phone || null, decoded.id]
    );

    if (userResult.affectedRows === 0) {
      throw new Error("Failed to update user profile");
    }

    const full_name = first_name && last_name ? `${first_name} ${last_name}` : null;

    // Check if student record exists
    const [checkStudent] = await connection.query<RowDataPacket[]>(
      "SELECT * FROM students WHERE user_id = ?",
      [decoded.id]
    );

    if (checkStudent.length === 0) {
      // Create new student record
      if (full_name || nationality || state || city || gender || program_type) {
        const [studentResult] = await connection.query<ResultSetHeader>(
          `INSERT INTO students (
            user_id, name, nationality, state, city, gender, prefered_program, created_at, updated_at
          ) VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())`,
          [
            decoded.id, 
            full_name || '', 
            nationality || null, 
            state || null, 
            city || null, 
            gender || null, 
            program_type || null
          ]
        );

        if (studentResult.affectedRows === 0) {
          throw new Error("Failed to create student profile");
        }
      }
    } else {
      // Update existing student record
      const studentUpdateQuery = `
        UPDATE students 
        SET 
          name = COALESCE(?, name),
          nationality = COALESCE(?, nationality),
          state = COALESCE(?, state),
          city = COALESCE(?, city),
          gender = COALESCE(?, gender),
          prefered_program = COALESCE(?, prefered_program),
          updated_at = NOW()
        WHERE user_id = ?
      `;
      
      const [studentResult] = await connection.query<ResultSetHeader>(
        studentUpdateQuery,
        [
          full_name || null, 
          nationality || null, 
          state || null, 
          city || null, 
          gender || null, 
          program_type || null,
          decoded.id
        ]
      );

      if (studentResult.affectedRows === 0) {
        throw new Error("Failed to update student profile");
      }
    }

    // Commit transaction
    await connection.commit();

    // Get updated user data to return
    const [updatedUser] = await connection.query<RowDataPacket[]>(
      `SELECT 
          u.id,
          u.first_name,
          u.last_name,
          u.email,
          u.phone,
          u.image as profile_picture,
          s.nationality,
          s.gender,
          s.city,
          s.state,
          s.prefered_program
      FROM users u
      LEFT JOIN students s ON u.id = s.user_id
      WHERE u.id = ?`,
      [decoded.id]
    );

    return NextResponse.json({
      success: true,
      message: "Profile updated successfully",
      data: updatedUser[0]
    }, { status: 200 });

  } catch (err: any) {
    await connection.rollback();
    console.error('Profile update error:', err);
    return NextResponse.json({
      success: false,
      message: err.message || "Internal server error"
    }, { status: 500 });
  } finally {
    connection.release();
  }
}