import prisma from '~/server/utils/prisma'

export default defineEventHandler(async (event) => {
  try {
    // Check authentication
    const user = event.context.user;
    if (!user || !user.userID) {
      return {
        statusCode: 401,
        body: { success: false, message: 'Unauthorized' }
      }
    }

    const query = getQuery(event)
    let logs = [];
    let totalLogs = 0;
    let failedDeliveries = 0;
    let successfulDeliveries = 0;
    let total = 0;

    try {
      // Define filters
      const filters = {}
      
      // Date range filter
      if (query.startDate) {
        filters.created_at = {
          ...filters.created_at,
          gte: new Date(query.startDate)
        }
      }
      
      if (query.endDate) {
        filters.created_at = {
          ...filters.created_at,
          lte: new Date(query.endDate)
        }
      }
      
      // Action filter
      if (query.action) {
        filters.action = query.action
      }
      
      // Channel filter
      if (query.channel) {
        filters.channel_type = query.channel
      }
      
      // Status filter
      if (query.status) {
        filters.status = query.status
      }
      
      // Actor/user filter
      if (query.actor) {
        filters.actor = {
          contains: query.actor
        }
      }
      
      // Notification ID filter
      if (query.notificationId) {
        filters.notification_id = query.notificationId
      }
      
      // Keyword search in details or error_message
      if (query.keyword) {
        filters.OR = [
          { details: { contains: query.keyword } },
          { error_message: { contains: query.keyword } }
        ]
      }
      
      // Pagination
      const page = parseInt(query.page) || 1
      const limit = parseInt(query.limit) || 10
      const skip = (page - 1) * limit
      
      try {
        console.log("Attempting to query notification_logs table...");
        
        // First check if the table exists
        let tableExists = true;
        try {
          await prisma.$queryRaw`SELECT 1 FROM notification_logs LIMIT 1`;
          console.log("notification_logs table exists!");
        } catch (tableCheckError) {
          console.error("Table check error:", tableCheckError.message);
          console.error("Table likely doesn't exist - you need to run the migration!");
          tableExists = false;
          throw new Error("notification_logs table does not exist");
        }
        
        if (tableExists) {
          // Get total count for pagination
          total = await prisma.notification_logs.count({
            where: filters
          })
          
          // Get logs with pagination and sorting
          logs = await prisma.notification_logs.findMany({
            where: filters,
            orderBy: {
              created_at: 'desc'
            },
            skip,
            take: limit
          })
          
          // Get summary stats
          totalLogs = await prisma.notification_logs.count()
          failedDeliveries = await prisma.notification_logs.count({
            where: {
              status: 'Failed'
            }
          })
          successfulDeliveries = await prisma.notification_logs.count({
            where: {
              status: 'Sent'
            }
          })
          
          console.log(`Successfully fetched ${logs.length} logs from database`);
        }
      } catch (dbError) {
        console.error("Database query error:", dbError.message);
        console.error("Stack trace:", dbError.stack);
        
        // Uncommenting the mock data code below will revert to using mock data
        // If you want to see real errors, keep this commented out
        
        /*
        // If the database table doesn't exist or there's another error, use mock data
        logs = generateMockLogs(limit);
        total = 25; // Mock total count
        totalLogs = 25;
        failedDeliveries = 3;
        successfulDeliveries = 20;
        */
        
        throw dbError; // Re-throw to see actual error in response
      }
    } catch (prismaError) {
      console.error("Prisma error:", prismaError.message);
      console.error("Stack trace:", prismaError.stack);
      
      // Uncommenting the mock data code below will revert to using mock data
      // If you want to see real errors, keep this commented out
      
      /*
      // If there's an issue with Prisma itself, use mock data
      logs = generateMockLogs(10);
      total = 25; // Mock total count
      totalLogs = 25;
      failedDeliveries = 3;
      successfulDeliveries = 20;
      */

      throw prismaError; // Re-throw to see actual error in response
    }
    
    // Calculate success rate
    const successRate = totalLogs > 0 
      ? Math.round((successfulDeliveries / totalLogs) * 100) 
      : 0
    
    const page = parseInt(query.page) || 1
    const limit = parseInt(query.limit) || 10
    
    return {
      statusCode: 200,
      body: {
        success: true,
        data: {
          logs,
          pagination: {
            page,
            limit,
            total,
            pages: Math.ceil(total / limit)
          },
          summary: {
            totalLogs,
            failedDeliveries,
            successfulDeliveries,
            successRate
          }
        }
      }
    }
  } catch (error) {
    console.error('Error fetching notification logs:', error)
    return {
      statusCode: 500,
      body: { 
        success: false, 
        message: 'Failed to fetch notification logs', 
        error: error.message,
        stack: error.stack
      }
    }
  }
})

// Helper function to generate mock logs for testing
function generateMockLogs(count = 10) {
  const actions = ['Notification Created', 'Notification Sent', 'Delivery Attempted', 'Notification Opened'];
  const statuses = ['Sent', 'Failed', 'Opened', 'Queued'];
  const channels = ['Email', 'SMS', 'Push Notification', 'Webhook'];
  const actors = ['System', 'Admin', 'API', 'Scheduler'];
  
  return Array.from({ length: count }, (_, i) => {
    const status = statuses[Math.floor(Math.random() * statuses.length)];
    const action = actions[Math.floor(Math.random() * actions.length)];
    const created_at = new Date();
    created_at.setHours(created_at.getHours() - Math.floor(Math.random() * 72)); // Random time in last 72 hours
    
    return {
      id: `mock-${i+1}-${Date.now()}`.substring(0, 36),
      notification_id: `notif-${i+1}-${Date.now()}`.substring(0, 36),
      action,
      actor: actors[Math.floor(Math.random() * actors.length)],
      actor_id: `user-${i+1}`,
      channel_type: channels[Math.floor(Math.random() * channels.length)],
      status,
      details: `${action} via ${channels[Math.floor(Math.random() * channels.length)]}`,
      source_ip: `192.168.1.${i+1}`,
      error_code: status === 'Failed' ? 'ERR_DELIVERY_FAILED' : null,
      error_message: status === 'Failed' ? 'Failed to deliver notification' : null,
      created_at
    };
  });
} 