import { z } from "zod";
import prisma from "~/server/utils/prisma";

const ENV = useRuntimeConfig();

function requireApiKey(event) {
  const headers = getRequestHeaders(event);
  const provided = headers["x-api-key"] || headers["X-API-Key"];
  const expected = ENV.notificationApiKey;
  if (!expected) {
    throw createError({
      statusCode: 500,
      statusMessage:
        "Notification API is not configured (missing NUXT_NOTIFICATION_API_KEY environment variable)",
    });
  }
  if (!provided || provided !== expected) {
    throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
  }
}

const listSchema = z.object({
  page: z
    .string()
    .optional()
    .transform((v) => (v ? parseInt(v) : 1))
    .default("1"),
  limit: z
    .string()
    .optional()
    .transform((v) => (v ? parseInt(v) : 20))
    .default("20"),
  status: z.string().optional(),
  priority: z.string().optional(),
  category: z.string().optional(),
  search: z.string().optional(),
  sortBy: z.string().default("created_at"),
  sortOrder: z.enum(["asc", "desc"]).default("desc"),
});

export default defineEventHandler(async (event) => {
  try {
    requireApiKey(event);
    const params = listSchema.parse(getQuery(event) || {});

    const where = {};
    if (params.status) where.status = params.status;
    if (params.priority) where.priority = params.priority;
    if (params.category)
      where.notification_categories = { value: params.category };
    if (params.search) {
      where.OR = [
        { title: { contains: params.search } },
        { email_subject: { contains: params.search } },
        { push_title: { contains: params.search } },
      ];
    }

    const total = await prisma.notifications.count({ where });

    const notifications = await prisma.notifications.findMany({
      where,
      select: {
        id: true,
        title: true,
        priority: true,
        status: true,
        delivery_type: true,
        scheduled_at: true,
        created_at: true,
        notification_categories: { select: { name: true } },
        notification_channels: { select: { channel_type: true } },
        notification_recipients: { select: { status: true } },
      },
      orderBy: { [params.sortBy]: params.sortOrder },
      skip: (params.page - 1) * params.limit,
      take: params.limit,
    });

    const items = notifications.map((n) => {
      const totalRecipients = n.notification_recipients.length;
      const delivered = n.notification_recipients.filter(
        (r) => r.status === "delivered"
      ).length;
      const successRate =
        totalRecipients > 0
          ? Math.round((delivered / totalRecipients) * 100)
          : 0;
      return {
        id: n.id,
        title: n.title,
        category: n.notification_categories?.name || "Uncategorized",
        channels: n.notification_channels.map((c) => c.channel_type),
        priority: n.priority,
        status: n.status,
        recipients: totalRecipients,
        successRate,
        createdAt: n.created_at,
      };
    });

    const totalPages = Math.ceil(total / params.limit);

    return {
      success: true,
      data: {
        notifications: items,
        pagination: {
          page: params.page,
          totalPages,
          totalItems: total,
          hasMore: params.page < totalPages,
        },
      },
    };
  } catch (error) {
    if (error instanceof z.ZodError) {
      throw createError({
        statusCode: 400,
        statusMessage: "Invalid query parameters",
        data: error.errors,
      });
    }
    if (error.statusCode) throw error;
    throw createError({
      statusCode: 500,
      statusMessage: "Failed to fetch notifications",
      data: { error: error.message },
    });
  }
});
