import { sendPushToUsers } from "../services/pushNotificationService.js";

const toNotificationItem = (row) => ({
  id: Number(row.id),
  user_id: Number(row.user_id),
  type: row.type,
  message: row.message,
  is_read: row.is_read,
  entity_id: row.entity_id === null ? null : Number(row.entity_id),
  created_at: row.created_at,
});

export const fetchCompanyNotificationRecipients = async (db, companyId) => {
  const { rows } = await db.query(
    `
      SELECT DISTINCT u.id
      FROM users u
      LEFT JOIN user_companies uc
        ON uc.user_id = u.id
      WHERE u.is_active = TRUE
        AND (
          u.company_id = $1
          OR uc.company_id = $1
        )
      ORDER BY u.id ASC
    `,
    [companyId],
  );

  return rows.map((row) => Number(row.id));
};

export const createNotificationsForUsers = async (
  db,
  { userIds, type, message, entityId = null, title = null, data = {} },
) => {
  if (!Array.isArray(userIds) || !userIds.length) {
    return [];
  }

  const { rows } = await db.query(
    `
      INSERT INTO notifications (
        user_id,
        type,
        message,
        is_read,
        entity_id
      )
      SELECT recipient_id, $2, $3, FALSE, $4
      FROM UNNEST($1::bigint[]) AS recipient_id
      RETURNING
        id,
        user_id,
        type,
        message,
        is_read,
        entity_id,
        TO_CHAR(created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') AS created_at
    `,
    [userIds, type, message, entityId],
  );

  const notifications = rows.map(toNotificationItem);

  await sendPushToUsers(db, {
    userIds,
    title: title || "MGX",
    body: message,
    data: {
      type,
      entity_id: entityId,
      ...data,
    },
  });

  return notifications;
};

export const createCompanyNotifications = async (
  db,
  { companyId, type, message, entityId = null, title = null, data = {} },
) => {
  const userIds = await fetchCompanyNotificationRecipients(db, companyId);

  return createNotificationsForUsers(db, {
    userIds,
    type,
    message,
    entityId,
    title,
    data,
  });
};

export const emitNotifications = (io, notifications) => {
  if (!io || !Array.isArray(notifications)) {
    return;
  }

  notifications.forEach((notification) => {
    io.to(`user:${notification.user_id}`).emit("notification:new", notification);
  });
};
