/**
 * Component: Notification Test API
 * Documentation: documentation/backend/services/notifications.md
 */

import { NextRequest, NextResponse } from 'next/server';
import { requireAuth, requireAdmin, AuthenticatedRequest } from '@/lib/middleware/auth';
import { getNotificationService, getRegisteredProviderTypes, NotificationPayload } from '@/lib/services/notification';
import { RMABLogger } from '@/lib/utils/logger';
import { z } from 'zod';
import { prisma } from '@/lib/db';

const logger = RMABLogger.create('API.Admin.Notifications.Test');

// Flexible schema: supports both backendId and type+config formats
const TestNotificationSchema = z.object({
  backendId: z.string().optional(),
  type: z.string().refine((val) => getRegisteredProviderTypes().includes(val), { message: 'Unsupported notification provider type' }).optional(),
  config: z.record(z.any()).optional(),
});

/**
 * POST /api/admin/notifications/test
 * Test notification with provided config (synchronous)
 */
export async function POST(request: NextRequest) {
  return requireAuth(request, async (req: AuthenticatedRequest) => {
    return requireAdmin(req, async () => {
      try {
        const body = await request.json();
        const parsed = TestNotificationSchema.parse(body);

        let type: string;
        let encryptedConfig: any;

        const notificationService = getNotificationService();

        if (parsed.backendId) {
          // Test existing backend by ID (uses stored config)
          const backend = await prisma.notificationBackend.findUnique({
            where: { id: parsed.backendId },
          });

          if (!backend) {
            return NextResponse.json(
              { error: 'NotFound', message: 'Backend not found' },
              { status: 404 }
            );
          }

          type = backend.type;
          encryptedConfig = backend.config; // Already encrypted in DB
        } else if (parsed.type && parsed.config) {
          // Test new config before saving
          type = parsed.type;
          encryptedConfig = notificationService.encryptConfig(type, parsed.config);
        } else {
          return NextResponse.json(
            { error: 'ValidationError', message: 'Must provide either backendId or type+config' },
            { status: 400 }
          );
        }

        // Create test payload
        const testPayload: NotificationPayload = {
          event: 'request_available',
          requestId: 'test-request-id',
          title: "The Hitchhiker's Guide to the Galaxy",
          author: 'Douglas Adams',
          userName: 'Test User',
          requestType: 'audiobook',
          timestamp: new Date(),
        };

        // Send test notification synchronously (not via job queue)
        try {
          // Call sendToBackend directly
          await notificationService.sendToBackend(type, encryptedConfig, testPayload);

          logger.info(`Test notification sent successfully for ${type}`, {
            adminId: req.user?.sub,
          });

          return NextResponse.json({
            success: true,
            message: 'Test notification sent successfully',
          });
        } catch (notificationError) {
          logger.error(`Test notification failed for ${type}`, {
            error: notificationError instanceof Error ? notificationError.message : String(notificationError),
            adminId: req.user?.sub,
          });

          return NextResponse.json(
            {
              error: 'NotificationError',
              message: notificationError instanceof Error ? notificationError.message : 'Failed to send test notification',
            },
            { status: 400 }
          );
        }
      } catch (error) {
        logger.error('Failed to test notification', {
          error: error instanceof Error ? error.message : String(error),
        });

        if (error instanceof z.ZodError) {
          return NextResponse.json(
            {
              error: 'ValidationError',
              details: error.errors,
            },
            { status: 400 }
          );
        }

        return NextResponse.json(
          {
            error: 'TestError',
            message: 'Failed to test notification',
          },
          { status: 500 }
        );
      }
    });
  });
}
