// app/api/appapis/cancel-appointment/[id]/route.js
import { NextRequest, NextResponse } from 'next/server';
import pool from '../../../../../lib/db/db';
import { RowDataPacket, ResultSetHeader } from 'mysql2';
import { verifyAuthentication } from '../../../../utils/verifyAuthentication';

// CORS headers
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,
  { params }
) {
  const connection = await pool.getConnection();
  
  try {
    const appointmentId = params.id;
    
    if (!appointmentId) {
      connection.release();
      return NextResponse.json(
        { success: false, message: 'Invalid appointment ID' },
        { status: 400, headers: corsHeaders }
      );
    }

    // Get token from Authorization header for mobile app
    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 authorized (student)
    if (decoded.role !== 'student') {
      connection.release();
      return NextResponse.json(
        { success: false, message: 'Access denied. Only students can cancel appointments.' },
        { status: 403, headers: corsHeaders }
      );
    }

    const studentId = decoded.id;
    
    // Check if student exists and is active
    const [studentExists] = await connection.query<RowDataPacket[]>(
      'SELECT id, first_name, last_name, email FROM users WHERE id = ? AND is_active = 1 AND user_type = "student"',
      [studentId]
    );

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

    // Start transaction
    await connection.beginTransaction();

    // 1. Check if appointment exists and belongs to this student
    const [appointment] = await connection.query<RowDataPacket[]>(
      `SELECT 
        fsbs.id, 
        fsbs.foreign_student_id,
        fsbs.session_date,
        fsbs.start_time,
        fsbs.end_time,
        fsbs.status as current_status,
        fsbs.amount,
        fs.name as tutor_name, 
        fs.email as tutor_email,
        fs.hour_rate as tutor_rate
      FROM foreign_student_booked_sessions fsbs
      INNER JOIN foreign_students fs ON fsbs.foreign_student_id = fs.id
      WHERE fsbs.id = ? AND fsbs.student_id = ?`,
      [appointmentId, studentId]
    );

    if (appointment.length === 0) {
      await connection.rollback();
      connection.release();
      return NextResponse.json(
        { success: false, message: 'Appointment not found or access denied' },
        { status: 404, headers: corsHeaders }
      );
    }

    const appointmentData = appointment[0];
    
    // 2. Check if appointment can be cancelled
    const appointmentDate = new Date(appointmentData.session_date);
    const [hours, minutes] = appointmentData.start_time.split(':');
    appointmentDate.setHours(parseInt(hours), parseInt(minutes), 0, 0);
    const currentTime = new Date();
    
    // Check if appointment is in the past
    if (appointmentDate < currentTime) {
      await connection.rollback();
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: 'Cannot cancel past appointments. The meeting time has already passed.',
          meeting_time: appointmentDate.toISOString()
        },
        { status: 400, headers: corsHeaders }
      );
    }

    // Check if appointment is already cancelled or completed
    if (['cancelled', 'completed'].includes(appointmentData.current_status)) {
      await connection.rollback();
      connection.release();
      return NextResponse.json(
        { 
          success: false, 
          message: `Appointment is already ${appointmentData.current_status}. Cannot cancel.` 
        },
        { status: 400, headers: corsHeaders }
      );
    }

    // 3. Update appointment status to cancelled
    const [updateResult] = await connection.query<ResultSetHeader>(
      `UPDATE foreign_student_booked_sessions 
       SET status = 'cancelled', updated_at = NOW()
       WHERE id = ? AND student_id = ?`,
      [appointmentId, studentId]
    );

    if (updateResult.affectedRows === 0) {
      await connection.rollback();
      connection.release();
      return NextResponse.json(
        { success: false, message: 'Failed to cancel appointment' },
        { status: 500, headers: corsHeaders }
      );
    }

    // Commit transaction
    await connection.commit();
    connection.release();

    // Format response times
    const formatDateTime = (date: Date) => {
      return date.toLocaleString('en-US', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
      });
    };

    return NextResponse.json({
      success: true,
      message: 'Appointment cancelled successfully',
      data: {
        appointment_id: appointmentId,
        tutor_name: appointmentData.tutor_name,
        session_date: appointmentData.session_date,
        start_time: appointmentData.start_time.substring(0, 5),
        end_time: appointmentData.end_time.substring(0, 5),
        formatted_meeting_time: formatDateTime(appointmentDate),
        amount_refunded: appointmentData.amount,
        cancellation_time: new Date().toISOString()
      }
    }, { status: 200, headers: corsHeaders });

  } catch (err: any) {
    // Rollback on any error
    if (connection) {
      await connection.rollback();
      connection.release();
    }
    
    console.error('Cancel appointment error:', err);
    
    return NextResponse.json(
      { 
        success: false, 
        message: err.message || 'Failed to cancel appointment. Please try again.' 
      },
      { status: 500, headers: corsHeaders }
    );
  }
}