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

// Define the token interface
interface TokenInterface {
  id: number;
  userId?: number;
  email?: string;
  role?: string;
}

// CORS headers helper
const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
  'Access-Control-Max-Age': '86400',
};

// Handle OPTIONS for CORS preflight
export async function OPTIONS() {
  return NextResponse.json({}, { 
    status: 200,
    headers: corsHeaders
  });
}

export async function GET(request: NextRequest) {
  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,
        headers: corsHeaders
      });
    }

    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,
        headers: corsHeaders
      });
    }

    const userId = decoded.id;

    // Get pagination parameters
    const { searchParams } = new URL(request.url);
    const page = parseInt(searchParams.get('page') || '1');
    const limit = parseInt(searchParams.get('limit') || '20');
    const filter = searchParams.get('filter') || 'all'; // 'all' or 'unread'
    const offset = (page - 1) * limit;

    // Build query based on filter
    let whereClause = "WHERE user_id = ?";
    const queryParams: any[] = [userId];

    if (filter === 'unread') {
      whereClause += " AND is_read = 0";
    }

    // Get total count for pagination
    const [countResult] = await pool.query<RowDataPacket[]>(
      `SELECT COUNT(*) as total FROM notifications ${whereClause}`,
      queryParams
    );
    const totalCount = countResult[0].total;
    const totalPages = Math.ceil(totalCount / limit);

    // Get notifications with pagination
    const [notifications] = await pool.query<RowDataPacket[]>(
      `SELECT 
        id, 
        type, 
        name, 
        email, 
        message, 
        user_id, 
        university_id, 
        consultant_id, 
        student_id,
        application_id, 
        is_read, 
        created_at,
        UNIX_TIMESTAMP(created_at) as timestamp
      FROM notifications 
      ${whereClause} 
      ORDER BY created_at DESC 
      LIMIT ? OFFSET ?`,
      [...queryParams, limit, offset]
    );

    // Get total unread count (for header)
    const [unreadResult] = await pool.query<RowDataPacket[]>(
      `SELECT COUNT(*) as count FROM notifications WHERE user_id = ? AND is_read = 0`,
      [userId]
    );
    const unreadCount = unreadResult[0].count;

    // Format the notifications
    const formattedNotifications = notifications.map(notification => ({
      id: notification.id,
      type: notification.type,
      title: getNotificationTitle(notification.type as string),
      description: notification.message || '',
      iconType: notification.type,
      name: notification.name,
      email: notification.email,
      universityId: notification.university_id,
      consultantId: notification.consultant_id,
      studentId: notification.student_id,
      applicationId: notification.application_id,
      isRead: notification.is_read === 1,
      createdAt: notification.created_at,
      timestamp: notification.timestamp,
      timeAgo: getTimeAgo(notification.created_at as string)
    }));

    return NextResponse.json({
      success: true,
      data: {
        notifications: formattedNotifications,
        unreadCount,
        totalCount,
        currentPage: page,
        totalPages,
        limit,
        filter
      }
    }, { 
      status: 200,
      headers: corsHeaders
    });

  } catch (error: any) {
    console.error('Notifications API error:', error);
    
    return NextResponse.json({
      success: false,
      message: "Internal Server Error",
      error: error.message
    }, { 
      status: 500,
      headers: corsHeaders
    });
  }
}

// Mark single notification as read/unread
export async function PATCH(request: NextRequest) {
  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,
        headers: corsHeaders
      });
    }

    const token = authHeader.substring(7);
    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"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    const body = await request.json();
    const { notificationId, isRead } = body;

    if (!notificationId) {
      return NextResponse.json({
        success: false,
        message: "Notification ID is required"
      }, { 
        status: 400,
        headers: corsHeaders
      });
    }

    // Update the notification read status
    const [result] = await pool.query<ResultSetHeader>(
      `UPDATE notifications 
       SET is_read = ? 
       WHERE id = ? AND user_id = ?`,
      [isRead ? 1 : 0, notificationId, decoded.id]
    );

    if (result.affectedRows === 0) {
      return NextResponse.json({
        success: false,
        message: "Notification not found or unauthorized"
      }, { 
        status: 404,
        headers: corsHeaders
      });
    }

    return NextResponse.json({
      success: true,
      message: isRead ? 'Notification marked as read' : 'Notification marked as unread',
      data: { 
        notificationId,
        isRead,
        affectedRows: result.affectedRows 
      }
    }, { 
      status: 200,
      headers: corsHeaders
    });

  } catch (error: any) {
    console.error('Notifications PATCH error:', error);
    return NextResponse.json({
      success: false,
      message: "Internal Server Error"
    }, { 
      status: 500,
      headers: corsHeaders
    });
  }
}

// Mark all as read
export async function POST(request: NextRequest) {
  try {
    const authHeader = request.headers.get('authorization');
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return NextResponse.json({
        success: false,
        message: "No valid authorization header found"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    const token = authHeader.substring(7);
    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"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    const body = await request.json();
    const { markAllAsRead } = body;

    // Handle mark all as read
    if (markAllAsRead) {
      const [result] = await pool.query<ResultSetHeader>(
        `UPDATE notifications SET is_read = 1 WHERE user_id = ? AND is_read = 0`,
        [decoded.id]
      );

      return NextResponse.json({
        success: true,
        message: 'All notifications marked as read',
        data: { affectedRows: result.affectedRows }
      }, { 
        status: 200,
        headers: corsHeaders
      });
    }

    return NextResponse.json({
      success: false,
      message: "Invalid request"
    }, { 
      status: 400,
      headers: corsHeaders
    });

  } catch (error: any) {
    console.error('Notifications POST error:', error);
    return NextResponse.json({
      success: false,
      message: "Internal Server Error"
    }, { 
      status: 500,
      headers: corsHeaders
    });
  }
}

// Delete notification(s)
export async function DELETE(request: NextRequest) {
  try {
    const authHeader = request.headers.get('authorization');
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return NextResponse.json({
        success: false,
        message: "No valid authorization header found"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    const token = authHeader.substring(7);
    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"
      }, { 
        status: 401,
        headers: corsHeaders
      });
    }

    const { searchParams } = new URL(request.url);
    const id = searchParams.get('id');

    let result;
    if (id) {
      // Delete specific notification
      [result] = await pool.query<ResultSetHeader>(
        `DELETE FROM notifications WHERE id = ? AND user_id = ?`,
        [id, decoded.id]
      );
    } else {
      // Delete all notifications for user
      [result] = await pool.query<ResultSetHeader>(
        `DELETE FROM notifications WHERE user_id = ?`,
        [decoded.id]
      );
    }

    return NextResponse.json({
      success: true,
      message: id ? 'Notification deleted' : 'All notifications cleared',
      data: { 
        affectedRows: result.affectedRows,
        deletedId: id || 'all' 
      }
    }, { 
      status: 200,
      headers: corsHeaders
    });

  } catch (error: any) {
    console.error('Notifications DELETE error:', error);
    return NextResponse.json({
      success: false,
      message: "Internal Server Error"
    }, { 
      status: 500,
      headers: corsHeaders
    });
  }
}

// Helper functions
function getNotificationTitle(type: string): string {
  const titles: Record<string, string> = {
    university: 'University Update',
    application: 'Application Update',
    student: 'Student Inquiry',
    system: 'System Notification',
    email: 'New Message',
    info: 'Notification'
  };
  return titles[type] || titles.info;
}

function getTimeAgo(dateString: string): string {
  if (!dateString) return 'Recently';
  
  const date = new Date(dateString);
  const now = new Date();
  const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);

  if (seconds < 60) return 'Just now';
  if (seconds < 3600) return Math.floor(seconds / 60) + ' minutes ago';
  if (seconds < 86400) return Math.floor(seconds / 3600) + ' hours ago';
  if (seconds < 604800) return Math.floor(seconds / 86400) + ' days ago';
  if (seconds < 2592000) return Math.floor(seconds / 604800) + ' weeks ago';
  if (seconds < 31536000) return Math.floor(seconds / 2592000) + ' months ago';
  return Math.floor(seconds / 31536000) + ' years ago';
}