// app/api/appapis/change-password/route.js
import { NextRequest, NextResponse } from 'next/server';
import pool from '../../../../lib/db/db';
import { ResultSetHeader, RowDataPacket } from 'mysql2';
import bcrypt from 'bcryptjs';
import { verifyAuthentication } from '../../../utils/verifyAuthentication';
import { changePasswordSchema as Schema } from '../../../../validations/passwordValidation';

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

// Handle OPTIONS for CORS preflight
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 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 ')) {
      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 TokenInterface;
    
    if (!decoded || !decoded.id) {
      connection.release();
      return NextResponse.json({
        success: false,
        message: "Invalid token - no user ID found"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    const body = await request.json();
    const parsed = Schema.parse(body);

    const {
      currentPassword,
      newPassword,
    } = parsed;

    // Start transaction
    await connection.beginTransaction();

    let validPassword = false;
    let updateResult = null;

    // Handle different user roles
    if (decoded.role === "foreign-student") {
      // Foreign student - check foreign_students table
      const [checkUser] = await connection.query<RowDataPacket[]>(
        "SELECT * FROM foreign_students WHERE id = ? AND is_active = 1", 
        [decoded.id]
      );

      if (checkUser.length === 0) {
        await connection.rollback();
        connection.release();
        return NextResponse.json({
          success: false,
          message: "Foreign student not found or account inactive"
        }, { 
          status: 401,
          headers: corsHeaders
        });
      }

      // Verify current password from foreign_students table
      validPassword = await bcrypt.compare(currentPassword, checkUser[0].password_hash);

      if (!validPassword) {
        await connection.rollback();
        connection.release();
        return NextResponse.json({
          success: false,
          message: "Current password is incorrect"
        }, { 
          status: 401,
          headers: corsHeaders
        });
      }

      // Hash new password
      const hashedPassword = await bcrypt.hash(newPassword, 10);

      // Update password in foreign_students table
      const [updatePassword] = await connection.query<ResultSetHeader>(
        "UPDATE foreign_students SET password_hash = ?, updated_at = NOW() WHERE id = ? AND is_active = 1", 
        [hashedPassword, decoded.id]
      );

      updateResult = updatePassword;

    } else if (decoded.role === "student" || decoded.role === "consultant") {
      // Student or Consultant - check users table
      const [checkUser] = await connection.query<RowDataPacket[]>(
        "SELECT * FROM users WHERE id = ? AND user_type IN ('student', 'consultant')", 
        [decoded.id]
      );

      if (checkUser.length === 0) {
        await connection.rollback();
        connection.release();
        return NextResponse.json({
          success: false,
          message: "You are not authorized to perform this action"
        }, { 
          status: 401,
          headers: corsHeaders
        });
      }

      // Verify current password
      validPassword = await bcrypt.compare(currentPassword, checkUser[0].password);

      if (!validPassword) {
        await connection.rollback();
        connection.release();
        return NextResponse.json({
          success: false,
          message: "Current password is incorrect"
        }, { 
          status: 401,
          headers: corsHeaders
        });
      }

      // Hash new password
      const hashedPassword = await bcrypt.hash(newPassword, 10);

      // Update password in users table
      const [updatePassword] = await connection.query<ResultSetHeader>(
        "UPDATE users SET password = ? WHERE id = ? AND user_type IN ('student', 'consultant')", 
        [hashedPassword, decoded.id]
      );

      updateResult = updatePassword;

    } else {
      await connection.rollback();
      connection.release();
      return NextResponse.json({
        success: false,
        message: "Invalid user role"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    // Check if password was updated successfully
    if (!updateResult || updateResult.affectedRows === 0) {
      await connection.rollback();
      connection.release();
      return NextResponse.json({
        success: false,
        message: "Failed to update password"
      }, { 
        status: 500,
        headers: corsHeaders
      });
    }

    // Commit transaction
    await connection.commit();

    connection.release();

    return NextResponse.json({
      success: true,
      message: "Password updated successfully"
    }, { 
      status: 200,
      headers: corsHeaders
    });

  } catch (err: any) {
    // Rollback transaction on error
    try {
      await connection.rollback();
    } catch (rollbackErr) {
      console.error("Rollback failed:", rollbackErr);
    }
    connection.release();

    // Handle Zod validation errors
    if (err?.issues) {
      const fieldErrors: Record<string, string[]> = {};
      for (const issue of err.issues) {
        const key = (issue.path?.[0] as string) ?? "_";
        fieldErrors[key] = fieldErrors[key] || [];
        fieldErrors[key].push(issue.message);
      }
      return NextResponse.json({
        success: false,
        message: fieldErrors
      }, { 
        status: 400,
        headers: corsHeaders
      });
    }

    console.error("Password update error:", err);
    return NextResponse.json({
      success: false,
      message: err.message || "Internal server error"
    }, { 
      status: 500,
      headers: corsHeaders
    });
  }
}