/**
 * Admin Webhook Events Routes
 *
 * Read-only endpoints for viewing PayPal webhook events received by the system.
 * Useful for debugging activation/payment event delivery.
 */

import { Router, Request, Response } from 'express';
import { Prisma, PrismaClient } from '@prisma/client';
import { authenticateAdmin } from '../../middleware/auth';
import { logger } from '../../utils/logger';
import { PaginatedResponse } from '../../types';

const router = Router();
const prisma = new PrismaClient();

interface WebhookEventListItem {
  id: string;
  paypal_event_id: string;
  event_type: string;
  resource_id: string | null;
  processed_at: string;
  retry_count: number;
  last_retry_at: string | null;
}

interface WebhookEventDetail extends WebhookEventListItem {
  payload: Prisma.JsonValue;
}

/**
 * GET /v1/admin/webhooks
 * List webhook events with pagination and filtering.
 * Payload is intentionally omitted from list view for bandwidth.
 */
router.get('/', authenticateAdmin, async (req: Request, res: Response) => {
  try {
    const {
      page = '1',
      limit = '50',
      eventType,
      from,
      to,
      sort = 'processed_at',
      order = 'desc',
    } = req.query;

    const pageNum = Math.max(1, parseInt(page as string, 10));
    const limitNum = Math.min(200, Math.max(1, parseInt(limit as string, 10)));
    const skip = (pageNum - 1) * limitNum;

    // Build where clause
    const where: Prisma.PayPalEventWhereInput = {};

    if (eventType) {
      where.event_type = {
        contains: eventType as string,
        mode: 'insensitive',
      };
    }

    if (from || to) {
      where.processed_at = {};
      if (from) {
        (where.processed_at as Prisma.DateTimeFilter).gte = new Date(from as string);
      }
      if (to) {
        (where.processed_at as Prisma.DateTimeFilter).lte = new Date(to as string);
      }
    }

    // Build order clause — valid sort fields for this model
    const validSortFields = ['processed_at', 'retry_count'];
    const sortField = validSortFields.includes(sort as string) ? (sort as string) : 'processed_at';
    const orderBy: Prisma.PayPalEventOrderByWithRelationInput = {
      [sortField]: order === 'asc' ? 'asc' : 'desc',
    };

    const [events, total] = await Promise.all([
      prisma.payPalEvent.findMany({
        where,
        skip,
        take: limitNum,
        orderBy,
        select: {
          id: true,
          paypal_event_id: true,
          event_type: true,
          resource_id: true,
          processed_at: true,
          retry_count: true,
          last_retry_at: true,
          // payload intentionally omitted from list
        },
      }),
      prisma.payPalEvent.count({ where }),
    ]);

    const totalPages = Math.ceil(total / limitNum);

    const response: PaginatedResponse<WebhookEventListItem> = {
      data: events.map((e) => ({
        id: e.id,
        paypal_event_id: e.paypal_event_id,
        event_type: e.event_type,
        resource_id: e.resource_id,
        processed_at: e.processed_at.toISOString(),
        retry_count: e.retry_count,
        last_retry_at: e.last_retry_at ? e.last_retry_at.toISOString() : null,
      })),
      pagination: {
        page: pageNum,
        limit: limitNum,
        total,
        totalPages,
        hasNext: pageNum < totalPages,
        hasPrev: pageNum > 1,
      },
    };

    res.json(response);
  } catch (error) {
    logger.error('Error fetching webhook events list', { error, adminId: req.admin?.id });
    res.status(500).json({
      error: true,
      code: 'INTERNAL_ERROR',
      message: 'Failed to fetch webhook events',
      timestamp: new Date().toISOString(),
    });
  }
});

/**
 * GET /v1/admin/webhooks/:id
 * Get full event detail including raw JSON payload.
 */
router.get('/:id', authenticateAdmin, async (req: Request, res: Response) => {
  try {
    const { id } = req.params;

    const event = await prisma.payPalEvent.findUnique({
      where: { id },
    });

    if (!event) {
      res.status(404).json({
        error: true,
        code: 'WEBHOOK_EVENT_NOT_FOUND',
        message: 'Webhook event not found',
        timestamp: new Date().toISOString(),
      });
      return;
    }

    const detail: WebhookEventDetail = {
      id: event.id,
      paypal_event_id: event.paypal_event_id,
      event_type: event.event_type,
      resource_id: event.resource_id,
      processed_at: event.processed_at.toISOString(),
      retry_count: event.retry_count,
      last_retry_at: event.last_retry_at ? event.last_retry_at.toISOString() : null,
      payload: event.payload,
    };

    res.json(detail);
  } catch (error) {
    logger.error('Error fetching webhook event detail', {
      error,
      eventId: req.params.id,
      adminId: req.admin?.id,
    });
    res.status(500).json({
      error: true,
      code: 'INTERNAL_ERROR',
      message: 'Failed to fetch webhook event details',
      timestamp: new Date().toISOString(),
    });
  }
});

export default router;
